void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if (params.mParticle) { continue; } LLRenderPass::applyModelMatrix(params); if (params.mGroup) { params.mGroup->rebuildMesh(); } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); } } } }
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask, std::vector<LLSpatialGroup*>& groups) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif LLSpatialBridge* last_bridge = NULL; LLSpatialPartition* last_part = NULL; glPushMatrix(); for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialPartition* part = group->mSpatialPartition; if (part != last_part) { LLSpatialBridge* bridge = part->asBridge(); if (bridge != last_bridge) { glPopMatrix(); glPushMatrix(); if (bridge) { glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); } last_bridge = bridge; } last_part = part; } LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if (params.mParticle) { continue; } params.mVertexBuffer->setBuffer(mask); U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer(); glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount, GL_UNSIGNED_INT, indices_pointer+params.mOffset); addIndicesDrawn(params.mCount); } } } glPopMatrix(); }
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if (params.mParticle) { continue; } LLRenderPass::applyModelMatrix(params); if (params.mGroup) { params.mGroup->rebuildMesh(); } // KL Batching Textures, taken from renderAlpha and fiddled to enable highlighting transparent to work if (params.mTextureList.size() > 1) { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); // not sure on this glColor4f(1,0,0,1); // KL someone set us up the bomb... make your peace for (U32 i = 0; i < params.mTextureList.size(); ++i) { if (params.mTextureList[i].notNull()) { gGL.getTexUnit(i)->bind(LLViewerFetchedTexture::sSmokeImagep, TRUE); } } } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); } } } }
void LLDrawPoolAlpha::renderAlpha(U32 mask, std::vector<LLSpatialGroup*>& groups) { #if !LL_RELEASE_FOR_DOWNLOAD LLGLState::checkClientArrays(mask); #endif LLSpatialBridge* last_bridge = NULL; LLSpatialPartition* last_part = NULL; glPushMatrix(); LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (std::vector<LLSpatialGroup*>::iterator i = groups.begin(); i != groups.end(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialPartition* part = group->mSpatialPartition; if (part != last_part) { LLSpatialBridge* bridge = part->asBridge(); if (bridge != last_bridge) { glPopMatrix(); glPushMatrix(); if (bridge) { glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix); } last_bridge = bridge; } // if (!last_part || part->mDepthMask != last_part->mDepthMask) // { // glDepthMask(part->mDepthMask); // } last_part = part; } renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE); } } glPopMatrix(); }
void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); // check to see if it's a particle and if it's "close" { if (LLPipeline::sImpostorRender) { gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); } else { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } } for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; llassert(group); llassert(group->mSpatialPartition); if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress. group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD && group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; LLRenderPass::applyModelMatrix(params); { if (params.mFullbright) { // Turn off lighting if it hasn't already been so. if (light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = fullbright_shader; } else { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } light_enabled = FALSE; } } // Turn on lighting if it isn't already. else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = simple_shader; } else { gPipeline.enableLightsDynamic(); } light_enabled = TRUE; } // If we need shaders, and we're not ALREADY using the proper shader, then bind it // (this way we won't rebind shaders unnecessarily). if(use_shaders && (current_shader != target_shader)) { llassert(target_shader != NULL); if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); } else { current_shader->bind(); } } else if (!use_shaders && current_shader != NULL) { if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); } LLGLSLShader::bindNoShader(); current_shader = NULL; } if (params.mGroup) { params.mGroup->rebuildMesh(); } if (params.mTexture.notNull()) { gGL.getTexUnit(0)->bind(params.mTexture.get()); if(params.mTexture.notNull()) { params.mTexture->addTextureStats(params.mVSize); } if (params.mTextureMatrix) { gGL.getTexUnit(0)->activate(); glMatrixMode(GL_TEXTURE); glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); gPipeline.mTextureMatrixOps++; } } } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. if (draw_glow_for_this_partition && params.mGlowColor.mV[3] > 0) { // install glow-accumulating blend mode gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) // glow doesn't use vertex colors from the mesh data params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR); glColor4ubv(params.mGlowColor.mV); // do the actual drawing, again params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); // restore our alpha blend mode gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); } if (params.mTextureMatrix && params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } } } } if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } if (!light_enabled) { gPipeline.enableLightsDynamic(); } }
void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; BOOL use_shaders = gPipeline.canUseVertexShaders(); for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; llassert(group); llassert(group->getSpatialPartition()); if (group->getSpatialPartition()->mRenderByGroup && !group->isDead()) { bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE; // <FS:LO> Dont suspend partical processing while particles are hidden, just skip over drawing them if(!(gPipeline.sRenderParticles) && ( group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE || group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE)) { continue; } // </FS:LO> bool draw_glow_for_this_partition = mVertexShaderLevel > 0; // no shaders = no glow. LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GROUP_LOOP); bool disable_cull = is_particle_or_hud_particle; LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0); LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; if ((params.mVertexBuffer->getTypeMask() & mask) != mask) { //FIXME! LL_WARNS() << "Missing required components, skipping render batch." << LL_ENDL; continue; } // Fix for bug - NORSPEC-271 // If the face is more than 90% transparent, then don't update the Depth buffer for Dof // We don't want the nearly invisible objects to cause of DoF effects if(pass == 1 && !LLPipeline::sImpostorRender) { LLFace* face = params.mFace; if(face) { const LLTextureEntry* tep = face->getTextureEntry(); if(tep) { if(tep->getColor().mV[3] < 0.1f) continue; } } } LLRenderPass::applyModelMatrix(params); LLMaterial* mat = NULL; if (deferred_render) { mat = params.mMaterial; } if (params.mFullbright) { // Turn off lighting if it hasn't already been so. if (light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = fullbright_shader; } else { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } light_enabled = FALSE; } } // Turn on lighting if it isn't already. else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = simple_shader; } else { gPipeline.enableLightsDynamic(); } light_enabled = TRUE; } if (deferred_render && mat) { U32 mask = params.mShaderMask; llassert(mask < LLMaterial::SHADER_COUNT); target_shader = &(gDeferredMaterialProgram[mask]); if (LLPipeline::sUnderWaterRender) { target_shader = &(gDeferredMaterialWaterProgram[mask]); } if (current_shader != target_shader) { gPipeline.bindDeferredShader(*target_shader); } } else if (!params.mFullbright) { target_shader = simple_shader; } else { target_shader = fullbright_shader; } if(use_shaders && (current_shader != target_shader)) {// If we need shaders, and we're not ALREADY using the proper shader, then bind it // (this way we won't rebind shaders unnecessarily). current_shader = target_shader; current_shader->bind(); } else if (!use_shaders && current_shader != NULL) { LLGLSLShader::bindNoShader(); current_shader = NULL; } if (use_shaders && mat) { // We have a material. Supply the appropriate data here. if (LLPipeline::sRenderDeferred) { current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]); current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity); current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f); if (params.mNormalMap) { params.mNormalMap->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); } if (params.mSpecularMap) { params.mSpecularMap->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); } } } else if (LLPipeline::sRenderDeferred && current_shader && (current_shader == simple_shader)) { current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, 1.0f, 1.0f, 1.0f, 1.0f); current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, 0.0f); LLViewerFetchedTexture::sFlatNormalImagep->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); LLViewerFetchedTexture::sWhiteImagep->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); } if (params.mGroup) { params.mGroup->rebuildMesh(); } bool tex_setup = false; if (use_shaders && params.mTextureList.size() > 1) { for (U32 i = 0; i < params.mTextureList.size(); ++i) { if (params.mTextureList[i].notNull()) { gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); } } } else { //not batching textures or batch has only 1 texture -- might need a texture matrix if (params.mTexture.notNull()) { params.mTexture->addTextureStats(params.mVSize); if (use_shaders && mat) { current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture); } else { gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ; } if (params.mTextureMatrix) { tex_setup = true; gGL.getTexUnit(0)->activate(); gGL.matrixMode(LLRender::MM_TEXTURE); gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix); gPipeline.mTextureMatrixOps++; } } else { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } } { LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH); gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0)); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); } // If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. if (current_shader && draw_glow_for_this_partition && // <FS:Ansariel> Re-add particle rendering optimization //params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE)) params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE) && (!params.mParticle || params.mHasGlow)) // </FS:Ansariel> { // <FS:Ansariel> LL materials support merge error LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_GLOW); // install glow-accumulating blend mode gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) // <FS:Ansariel> LL materials support merge error //emissive_shader->bind(); // //params.mVertexBuffer->setBuffer((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); params.mVertexBuffer->setBuffer(mask | LLVertexBuffer::MAP_EMISSIVE); // </FS:Ansariel> // do the actual drawing, again params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); // restore our alpha blend mode // <FS:Ansariel> LL materials support merge error //gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); //current_shader->bind(); // </FS:Ansariel> } if (tex_setup) { gGL.getTexUnit(0)->activate(); gGL.loadIdentity(); gGL.matrixMode(LLRender::MM_MODELVIEW); } } } } gGL.setSceneBlendType(LLRender::BT_ALPHA); LLVertexBuffer::unbind(); if (!light_enabled) { gPipeline.enableLightsDynamic(); } }
void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); // check to see if it's a particle and if it's "close" { if (LLPipeline::sImpostorRender) { gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); } else { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } } for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i) { LLSpatialGroup* group = *i; if (group->mSpatialPartition->mRenderByGroup && !group->isDead()) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA]; for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; LLRenderPass::applyModelMatrix(params); if (params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(params.mTexture.get()); if (params.mTextureMatrix) { glMatrixMode(GL_TEXTURE); glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); gPipeline.mTextureMatrixOps++; } } if (params.mFullbright) { // Turn off lighting if it hasn't already been so. if (light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = fullbright_shader; } else { gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } light_enabled = FALSE; } } // Turn on lighting if it isn't already. else if (!light_enabled || !initialized_lighting) { initialized_lighting = TRUE; if (use_shaders) { target_shader = simple_shader; } else { gPipeline.enableLightsDynamic(); } light_enabled = TRUE; } // If we need shaders, and we're not ALREADY using the proper shader, then bind it // (this way we won't rebind shaders unnecessarily). if(use_shaders && (current_shader != target_shader)) { llassert(target_shader != NULL); if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); } else { current_shader->bind(); } } else if (!use_shaders && current_shader != NULL) { LLGLSLShader::bindNoShader(); if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); } current_shader = NULL; } if (params.mGroup) { params.mGroup->rebuildMesh(); } params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); if (params.mTextureMatrix && params.mTexture.notNull()) { gGL.getTexUnit(0)->activate(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } } } } if (!light_enabled) { gPipeline.enableLightsDynamic(); } }