diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 6b60481eb..b5c1603a0 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -187,7 +187,7 @@ volatile U8* LLVBOPool::allocate(U32& name, U32 size, bool for_seed) if (LLVertexBuffer::sDisableVBOMapping || mUsage != GL_DYNAMIC_DRAW_ARB) { glBufferDataARB(mType, size, 0, mUsage); - ret = (U8*) ll_aligned_malloc_16(size); + ret = (U8*) ll_aligned_malloc(size, 64); } else { //always use a true hint of static draw when allocating non-client-backed buffers @@ -240,7 +240,7 @@ void LLVBOPool::release(U32 name, volatile U8* buffer, U32 size) llassert(vbo_block_size(size) == size); deleteBuffer(name); - ll_aligned_free_16((U8*) buffer); + ll_aligned_free((U8*) buffer); if (mType == GL_ARRAY_BUFFER_ARB) { @@ -294,7 +294,7 @@ void LLVBOPool::cleanup() if (r.mClientData) { - ll_aligned_free_16((void*) r.mClientData); + ll_aligned_free((void*) r.mClientData); } l.pop_front(); @@ -356,6 +356,13 @@ static std::string vb_type_name[] = "TYPE_INDEX", }; +// static +const std::string& LLVertexBuffer::getTypeName(U8 i) +{ + llassert_always(i < (U8)(sizeof(vb_type_name) / sizeof(std::string))); + return vb_type_name[i]; +} + U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = { GL_TRIANGLES, diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index ea5aca583..d33bc9ff4 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -119,6 +119,8 @@ public: return *this; } + static const std::string& getTypeName(U8 i); + static LLVBOPool sStreamVBOPool; static LLVBOPool sDynamicVBOPool; static LLVBOPool sStreamIBOPool; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 0a2a7f1c0..fad98ddbd 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -112,7 +112,7 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) } else { - simple_shader = &gDeferredAlphaProgram; + simple_shader = &gDeferredAlphaProgram; fullbright_shader = &gDeferredFullbrightProgram; } @@ -158,11 +158,12 @@ void LLDrawPoolAlpha::beginPostDeferredPass(S32 pass) } deferred_render = TRUE; - if (mVertexShaderLevel > 0) - { - // Start out with no shaders. - current_shader = target_shader = NULL; - } + + // Start out with no shaders. + current_shader = target_shader = NULL; + + LLGLSLShader::bindNoShader(); + gPipeline.enableLightsDynamic(); } @@ -207,12 +208,14 @@ void LLDrawPoolAlpha::beginRenderPass(S32 pass) emissive_shader = &gObjectEmissiveProgram; } + // Start out with no shaders. + current_shader = target_shader = NULL; + if (mVertexShaderLevel > 0) { - // Start out with no shaders. - current_shader = target_shader = NULL; LLGLSLShader::bindNoShader(); } + gPipeline.enableLightsDynamic(); } @@ -429,88 +432,69 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) } LLRenderPass::applyModelMatrix(params); + + // Singu Note: Logic reordered here. Removed a fair bit of unneeded condition checks (mostly related to deferred mode), and made + // shader selection more explicit. - LLMaterial* mat = NULL; - - if (deferred_render) + if (params.mGroup) { - mat = params.mMaterial; + params.mGroup->rebuildMesh(); } + + LLMaterial* mat = deferred_render ? params.mMaterial.get() : NULL; - if (params.mFullbright) + if (!use_shaders) { - // Turn off lighting if it hasn't already been so. - if (light_enabled || !initialized_lighting) + llassert_always(!target_shader); + llassert_always(!current_shader); + llassert_always(!LLGLSLShader::sNoFixedFunction); + llassert_always(!LLGLSLShader::sCurBoundShaderPtr); + + if(params.mFullbright == 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) + light_enabled = !params.mFullbright; + initialized_lighting = true; + + if (light_enabled) // Turn off lighting if it hasn't already been so. { - target_shader = simple_shader; + gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); } - else + else // Turn on lighting if it isn't already. { 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). + if (mat) + { + U32 mask = params.mShaderMask; + + llassert(mask < LLMaterial::SHADER_COUNT); + target_shader = LLPipeline::sUnderWaterRender ? &(gDeferredMaterialWaterProgram[mask]) : &(gDeferredMaterialProgram[mask]); + + // 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 (current_shader != target_shader) + { + gPipeline.bindDeferredShader(*target_shader); + } + } + else + { + target_shader = params.mFullbright ? fullbright_shader : simple_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). + if(current_shader != target_shader) + { + target_shader->bind(); + } + } 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) + + if(mat) { 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); @@ -526,42 +510,37 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) { params.mSpecularMap->addTextureStats(params.mVSize); current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); - } + } + } + else if(deferred_render && 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); } - } 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) + if (params.mTextureList.size() > 1) { - 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()) + for (U32 i = 0; i < params.mTextureList.size(); ++i) { - gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + if (params.mTextureList[i].notNull()) + { + gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE); + } } } } - else + + bool tex_setup = false; + if(!use_shaders || params.mTextureList.size() <= 1) { //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) + if (mat) { current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, params.mTexture); } @@ -588,8 +567,9 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass) static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_PUSH("Alpha Push Verts"); { LLFastTimer t(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)); + gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor); + // Singu Note: Only remove tan/texcoord1/texcoord2 if actually using the fullbright shader. Material faces ignore fullbright bit. + params.mVertexBuffer->setBuffer(mask & ~((current_shader == fullbright_shader) ? (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); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 77dc1e6c4..43ff1335a 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -527,8 +527,6 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { gGL.multMatrix((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } - - gGL.diffuseColor4fv(color.mV); if (mDrawablep->isState(LLDrawable::RIGGED)) { @@ -542,6 +540,9 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) glPolygonOffset(-1.f, -1.f); gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix); const LLVolumeFace& vol_face = rigged->getVolumeFace(getTEOffset()); + + // Singu Note: Implementation changed to utilize a VBO, avoiding fixed functions unless required +#if 0 LLVertexBuffer::unbind(); glVertexPointer(3, GL_FLOAT, 16, vol_face.mPositions); if (vol_face.mTexCoords) @@ -552,14 +553,59 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) gGL.syncMatrices(); glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#else + LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; + + if(LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE)) + { + if(cur_shader != &gHighlightProgram) + { + gHighlightProgram.bind(); + } + } + + gGL.diffuseColor4fv(color.mV); + + LLPointer temp = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, 0); + + temp->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true); + + LLStrider indicesp; + LLStrider verticesp; + LLStrider texcoordsp; + temp->getIndexStrider(indicesp); + temp->getVertexStrider(verticesp); + temp->getTexCoord0Strider(texcoordsp); + + S32 vert_size = vol_face.mNumVertices*sizeof(LLVector4a); + S32 idx_size = (vol_face.mNumIndices*sizeof(U16)+0xF) & ~0xF; + S32 tc_size = (vol_face.mNumVertices*sizeof(LLVector2)+0xF) & ~0xF; + + LLVector4a::memcpyNonAliased16((F32*)verticesp.get(), (F32*) vol_face.mPositions, vert_size); + LLVector4a::memcpyNonAliased16((F32*)indicesp.get(), (F32*) vol_face.mIndices, idx_size); + LLVector4a::memcpyNonAliased16((F32*)texcoordsp.get(), (F32*) vol_face.mTexCoords, tc_size); + + temp->setBuffer(temp->getTypeMask()); + temp->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); + + if(LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE)) + { + if(cur_shader != &gHighlightProgram) + { + cur_shader->bind(); + } + } +#endif } } } else { + gGL.diffuseColor4fv(color.mV); LLGLEnable poly_offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f,-1.f); - mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask()); + // Singu Note: Disable per-vertex color to prevent fixed-function pipeline from using it. We want glColor color, not vertex color! + mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask() & ~(LLVertexBuffer::MAP_COLOR)); mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0bc4f4b91..371c23580 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4828,7 +4828,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (gPipeline.canUseWindLightShadersOnObjects() && LLPipeline::sRenderBump) { - if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull()) + // Singu Note: Don't check the materials ID, as doing such causes a mismatch between rebuildGeom and genDrawInfo. + // If we did check, then genDrawInfo would be more lenient than rebuildGeom on deciding if a face verts should have material-related attributes, + // which would result in a face with a vertex buffer that fails to meet shader attribute requirements. + if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() /* && !te->getMaterialID().isNull()*/) { LLMaterial* mat = te->getMaterialParams().get(); if (mat->getNormalID().notNull()) @@ -4943,7 +4946,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) //PROCESS NON-ALPHA FACES U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO - U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; + U32 bump_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1; U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 norm_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TANGENT; @@ -5392,6 +5395,38 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac buffer_usage = GL_STREAM_DRAW_ARB; } + // Singu Note: Catch insufficient vbos right when they are created. Easier to debug. + if(gDebugGL) + { + const LLTextureEntry* te = facep->getTextureEntry(); + if (mat && LLPipeline::sRenderDeferred && !hud_group && + !no_materials && + !te->getFullbright() && + !(te->getColor().mV[3] < 0.999f) && + !(te->getBumpmap() && (te->getBumpmap() < 18) && (mat->getNormalID().isNull()))) + { + U32 shader_mask = mat->getShaderMask(); + if(shader_mask != 1 && shader_mask != 5 && shader_mask != 9 && shader_mask != 13) + { + LLGLSLShader* shader = &(gDeferredMaterialProgram[shader_mask]); + + if((mask & shader->mAttributeMask) != shader->mAttributeMask) + { + for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) + { + U32 attrib_mask = 1 << i; + if((shader->mAttributeMask & attrib_mask) && !(mask & attrib_mask)) + { + const std::string& type_name = LLVertexBuffer::getTypeName(i); + llwarns << " Missing: " << type_name << llendl; + } + } + llerrs << "Face VBO missing required materials attributes." << llendl; + } + } + } + } + //create vertex buffer LLVertexBuffer* buffer = NULL; @@ -5532,7 +5567,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac { registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } - else if (te->getColor().mV[3] < 0.999f) + else if (!opaque) //Just use opaque instead of te->getColorblahblah { registerFace(group, facep, LLRenderPass::PASS_ALPHA); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7d2095334..b0fb54512 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3936,129 +3936,99 @@ void render_hud_elements() gGL.flush(); } +// Singu Note: Created to avoid redundant code. +void renderSelectedFaces(LLGLSLShader& shader, std::vector &selected_faces, LLViewerTexture* tex, LLColor4 color, LLRender::eTexIndex channel, LLRender::eTexIndex active_channel = LLRender::NUM_TEXTURE_CHANNELS) +{ + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + shader.bind(); + } + + bool active = active_channel == LLRender::NUM_TEXTURE_CHANNELS || channel == active_channel; + + if(!active) //Draw 'faded out' overlay for selected faces that aren't applicable to current channel being edited. + color.mV[3] *= .5f; + + for (std::vector::iterator it = selected_faces.begin(); it != selected_faces.end(); ++it) + { + LLFace *facep = *it; + if (!facep || facep->getDrawable()->isDead()) + { + llerrs << "Bad face on selection" << llendl; + return; + } + + const LLTextureEntry* te = facep->getTextureEntry(); + LLMaterial* mat = te ? te->getMaterialParams() : NULL; + + if(channel == LLRender::DIFFUSE_MAP) + { + if(active || !mat || + (active_channel == LLRender::NORMAL_MAP && mat->getNormalID().isNull()) || + (active_channel == LLRender::SPECULAR_MAP && mat->getSpecularID().isNull())) + facep->renderSelected(tex, color); + } + else if(channel == LLRender::NORMAL_MAP) + { + if(mat && mat->getNormalID().notNull()) + facep->renderSelected(tex, color); + } + else if(channel == LLRender::SPECULAR_MAP) + { + if(mat && mat->getSpecularID().notNull()) + facep->renderSelected(tex, color); + } + } + + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + shader.unbind(); + } +} void LLPipeline::renderHighlights() { assertInitialized(); - // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) - // Render highlighted faces. - LLGLSPipelineAlpha gls_pipeline_alpha; - LLColor4 color(1.f, 1.f, 1.f, 0.5f); - LLGLEnable color_mat(GL_COLOR_MATERIAL); - disableLights(); + if(!hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + return; //Nothing to draw... - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep) + // Setup + if ( !mFaceSelectImagep) { mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT); } - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP)) - { - // Make sure the selection image gets downloaded and decoded - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + // Make sure the selection image gets downloaded and decoded + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - llerrs << "Bad face on selection" << llendl; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - } + // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD) + // Render highlighted faces. + LLGLSPipelineAlpha gls_pipeline_alpha; + LLGLEnable color_mat(GL_COLOR_MATERIAL); + disableLights(); - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) - { - // Paint 'em red! - color.setVec(1.f, 0.f, 0.f, 0.5f); - - int count = mHighlightFaces.size(); - for (S32 i = 0; i < count; i++) - { - LLFace* facep = mHighlightFaces[i]; - facep->renderSelected(LLViewerTexture::sNullImagep, color); - } - } + // Singu Note: Logic here changed, and behavior changed as well. Always draw overlays of some nature over all selected faces. + // Faces that wont undergo any change if the current active channel is edited should have a 'faded' overlay + + // Temporary. If not deferred, then texcoord1 and texcoord2 are probably absent from face vbo, which LLFace::renderSelected piggybacks. + // Force to standard diffuse mode. Workaround would probably be to generate new face vbo data on the fly if required texcoord data is absent. + LLRender::eTexIndex active_channel = LLPipeline::sRenderDeferred ? sRenderHighlightTextureChannel : LLRender::NUM_TEXTURE_CHANNELS; + + // Default diffuse mapping + renderSelectedFaces(gHighlightProgram, mSelectedFaces, mFaceSelectImagep, LLColor4(1.f,1.f,1.f,.5f), LLRender::DIFFUSE_MAP, active_channel); + + // Paint 'em red! + renderSelectedFaces(gHighlightProgram, mHighlightFaces, LLViewerTexture::sNullImagep, LLColor4(1.f,0.f,0.f,.5f), LLRender::DIFFUSE_MAP); + + // Normal mapping + if(active_channel == LLRender::NORMAL_MAP) + renderSelectedFaces(gHighlightNormalProgram, mSelectedFaces, mFaceSelectImagep, LLColor4(1.f, .5f, .5f, .5f), LLRender::NORMAL_MAP); + + // Specular mapping + if(active_channel == LLRender::SPECULAR_MAP) + renderSelectedFaces(gHighlightSpecularProgram, mSelectedFaces, mFaceSelectImagep, LLColor4(0.f, .3f, 1.f, .8f), LLRender::SPECULAR_MAP); - // Contains a list of the faces of objects that are physical or - // have touch-handlers. mHighlightFaces.clear(); - - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) - { - gHighlightProgram.unbind(); - } - - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) - { - color.setVec(1.0f, 0.5f, 0.5f, 0.5f); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightNormalProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - llerrs << "Bad face on selection" << llendl; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightNormalProgram.unbind(); - } - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) - { - color.setVec(0.0f, 0.3f, 1.0f, 0.8f); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.bind(); - gGL.diffuseColor4f(1,1,1,0.5f); - } - - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); - - U32 count = mSelectedFaces.size(); - for (U32 i = 0; i < count; i++) - { - LLFace *facep = mSelectedFaces[i]; - if (!facep || facep->getDrawable()->isDead()) - { - llerrs << "Bad face on selection" << llendl; - return; - } - - facep->renderSelected(mFaceSelectImagep, color); - } - - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightSpecularProgram.unbind(); - } - } } //debug use