void LLTexUnit::refreshState(void) { // We set dirty to true so that the tex unit knows to ignore caching // and we reset the cached tex unit state gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); if (mCurrTexType != TT_NONE) { glEnable(sGLTextureType[mCurrTexType]); glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } if (mCurrBlendType != TB_COMBINE) { setTextureBlendType(mCurrBlendType); } else { setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false); setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true); } }
void LLTexUnit::setColorScale(S32 scale) { if (mCurrColorScale != scale || gGL.mDirty) { mCurrColorScale = scale; gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_RGB_SCALE, scale ); } }
void LLTexUnit::setAlphaScale(S32 scale) { if (mCurrAlphaScale != scale || gGL.mDirty) { mCurrAlphaScale = scale; gGL.flush(); glTexEnvi( GL_TEXTURE_ENV, GL_ALPHA_SCALE, scale ); } }
void LLTexUnit::activate(void) { if (mIndex < 0) return; if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty) { gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); gGL.mCurrTextureUnitIndex = mIndex; } }
bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; gGL.flush(); if (texture == NULL) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } if (!texture->getTexName()) //if texture does not exist { //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; return texture->bindDefaultImage(mIndex); } #if !LL_RELEASE_FOR_DOWNLOAD if(for_rendering) { int w = texture->getWidth(texture->getDiscardLevel()) ; int h = texture->getHeight(texture->getDiscardLevel()) ; if(w * h == LLImageGL::sCurTexPickSize) { texture->updateBindStats(); return bind(LLImageGL::sDefaultTexturep.get()); } } #endif if ((mCurrTexture != texture->getTexName()) || forceBind) { activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); texture->updateBindStats(); texture->setActive() ; mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { texture->mTexOptionsDirty = false; setTextureAddressMode(texture->mAddressMode); setTextureFilteringOption(texture->mFilterOption); } } return true; }
bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; gGL.flush(); LLImageGL* gl_tex = NULL ; if (texture == NULL || !(gl_tex = texture->getGLTexture())) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } if (!gl_tex->getTexName()) //if texture does not exist { //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; gl_tex->forceUpdateBindStats() ; return texture->bindDefaultImage(mIndex); } //in audit, replace the selected texture by the default one. if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) { if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) { gl_tex->updateBindStats(gl_tex->mTextureMemory); return bind(LLImageGL::sHighlightTexturep.get()); } } if ((mCurrTexture != gl_tex->getTexName()) || forceBind) { activate(); enable(gl_tex->getTarget()); mCurrTexture = gl_tex->getTexName(); glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) { texture->setActive() ; texture->updateBindStatsForTester() ; } mHasMipMaps = gl_tex->mHasMipMaps; if (gl_tex->mTexOptionsDirty) { gl_tex->mTexOptionsDirty = false; setTextureAddressMode(gl_tex->mAddressMode); setTextureFilteringOption(gl_tex->mFilterOption); } } return true; }
void LLTexUnit::disable(void) { if (mIndex < 0) return; if (mCurrTexType != TT_NONE) { activate(); unbind(mCurrTexType); gGL.flush(); glDisable(sGLTextureType[mCurrTexType]); mCurrTexType = TT_NONE; } }
void LLTexUnit::setTextureAddressMode(eTextureAddressMode mode) { if (mIndex < 0 || mCurrTexture == 0) return; gGL.flush(); activate(); glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_S, sGLAddressMode[mode]); glTexParameteri (sGLTextureType[mCurrTexType], GL_TEXTURE_WRAP_T, sGLAddressMode[mode]); if (mCurrTexType == TT_CUBE_MAP) { glTexParameteri (GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, sGLAddressMode[mode]); } }
bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { if (mIndex < 0) return false; if(mCurrTexture != texture) { gGL.flush(); activate(); enable(type); mCurrTexture = texture; glBindTexture(sGLTextureType[type], texture); mHasMipMaps = hasMips; } return true; }
void LLTexUnit::unbind(eTextureType type) { stop_glerror(); if (mIndex < 0) return; // Disabled caching of binding state. if (mCurrTexType == type) { gGL.flush(); activate(); mCurrTexture = 0; glBindTexture(sGLTextureType[type], 0); } }
void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions option) { if (mIndex < 0 || mCurrTexture == 0) return; gGL.flush(); if (option == TFO_POINT) { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MAG_FILTER, GL_LINEAR); } if (option >= TFO_TRILINEAR && mHasMipMaps) { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else if (option >= TFO_BILINEAR) { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_MIN_FILTER, GL_NEAREST); } if (gGLManager.mHasAnisotropic) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { if (gGL.mMaxAnisotropy < 1.f) { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy); llinfos << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << llendl ; gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ; } glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy); } else { glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); } } }
void LLTexUnit::enable(eTextureType type) { if (mIndex < 0) return; if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) ) { activate(); if (mCurrTexType != TT_NONE && !gGL.mDirty) { disable(); // Force a disable of a previous texture type if it's enabled. } mCurrTexType = type; gGL.flush(); glEnable(sGLTextureType[type]); } }
void LLTexUnit::refreshState(void) { // We set dirty to true so that the tex unit knows to ignore caching // and we reset the cached tex unit state gGL.flush(); glActiveTextureARB(GL_TEXTURE0_ARB + mIndex); // // Per apple spec, don't call glEnable/glDisable when index exceeds max texture units // http://www.mailinglistarchive.com/html/[email protected]/2008-07/msg00653.html // bool enableDisable = (mIndex < gGLManager.mNumTextureUnits); if (mCurrTexType != TT_NONE) { if (enableDisable) { glEnable(sGLTextureType[mCurrTexType]); } glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture); } else { if (enableDisable) { glDisable(GL_TEXTURE_2D); } glBindTexture(GL_TEXTURE_2D, 0); } if (mCurrBlendType != TB_COMBINE) { setTextureBlendType(mCurrBlendType); } else { setTextureCombiner(mCurrColorOp, mCurrColorSrc1, mCurrColorSrc2, false); setTextureCombiner(mCurrAlphaOp, mCurrAlphaSrc1, mCurrAlphaSrc2, true); } }
void LLTexUnit::setTextureBlendType(eTextureBlendType type) { if (mIndex < 0) return; // Do nothing if it's already correctly set. if (mCurrBlendType == type && !gGL.mDirty) { return; } gGL.flush(); activate(); mCurrBlendType = type; S32 scale_amount = 1; switch (type) { case TB_REPLACE: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); break; case TB_ADD: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); break; case TB_MULT: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); break; case TB_MULT_X2: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); scale_amount = 2; break; case TB_ALPHA_BLEND: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); break; case TB_COMBINE: glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); break; default: llerrs << "Unknown Texture Blend Type: " << type << llendl; break; } setColorScale(scale_amount); setAlphaScale(1); }
bool LLTexUnit::bind(LLCubeMap* cubeMap) { if (mIndex < 0) return false; gGL.flush(); if (cubeMap == NULL) { llwarns << "NULL LLTexUnit::bind cubemap" << llendl; return false; } if (cubeMap->mImages[0].isNull()) { llwarns << "NULL LLTexUnit::bind cubeMap->mImages[0]" << llendl; return false; } if (mCurrTexture != cubeMap->mImages[0]->getTexName()) { if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) { activate(); enable(LLTexUnit::TT_CUBE_MAP); mCurrTexture = cubeMap->mImages[0]->getTexName(); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); if (cubeMap->mImages[0]->mTexOptionsDirty) { cubeMap->mImages[0]->mTexOptionsDirty = false; setTextureAddressMode(cubeMap->mImages[0]->mAddressMode); setTextureFilteringOption(cubeMap->mImages[0]->mFilterOption); } return true; } else { llwarns << "Using cube map without extension!" << llendl; return false; } } return true; }
bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) { if (mIndex < 0) return false; gGL.flush(); if (bindDepth) { if (renderTarget->hasStencil()) { llerrs << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl; } bindManual(renderTarget->getUsage(), renderTarget->getDepth()); } else { bindManual(renderTarget->getUsage(), renderTarget->getTexture()); } return true; }
bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; if(!texture) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } if(!texture->getTexName()) { if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) { return bind(LLImageGL::sDefaultGLTexture) ; } return false ; } if ((mCurrTexture != texture->getTexName()) || forceBind) { gGL.flush(); activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); texture->updateBindStats(texture->mTextureMemory); mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { texture->mTexOptionsDirty = false; setTextureAddressMode(texture->mAddressMode); setTextureFilteringOption(texture->mFilterOption); } } return true; }
void LLTexUnit::setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha) { if (mIndex < 0) return; activate(); if (mCurrBlendType != TB_COMBINE || gGL.mDirty) { mCurrBlendType = TB_COMBINE; gGL.flush(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); } // We want an early out, because this function does a LOT of stuff. if ( ( (isAlpha && (mCurrAlphaOp == op) && (mCurrAlphaSrc1 == src1) && (mCurrAlphaSrc2 == src2)) || (!isAlpha && (mCurrColorOp == op) && (mCurrColorSrc1 == src1) && (mCurrColorSrc2 == src2)) ) && !gGL.mDirty) { return; } gGL.flush(); // Get the gl source enums according to the eTextureBlendSrc sources passed in GLint source1 = getTextureSource(src1); GLint source2 = getTextureSource(src2); // Get the gl operand enums according to the eTextureBlendSrc sources passed in GLint operand1 = getTextureSourceType(src1, isAlpha); GLint operand2 = getTextureSourceType(src2, isAlpha); // Default the scale amount to 1 S32 scale_amount = 1; GLenum comb_enum, src0_enum, src1_enum, src2_enum, operand0_enum, operand1_enum, operand2_enum; if (isAlpha) { // Set enums to ALPHA ones comb_enum = GL_COMBINE_ALPHA_ARB; src0_enum = GL_SOURCE0_ALPHA_ARB; src1_enum = GL_SOURCE1_ALPHA_ARB; src2_enum = GL_SOURCE2_ALPHA_ARB; operand0_enum = GL_OPERAND0_ALPHA_ARB; operand1_enum = GL_OPERAND1_ALPHA_ARB; operand2_enum = GL_OPERAND2_ALPHA_ARB; // cache current combiner mCurrAlphaOp = op; mCurrAlphaSrc1 = src1; mCurrAlphaSrc2 = src2; } else { // Set enums to RGB ones comb_enum = GL_COMBINE_RGB_ARB; src0_enum = GL_SOURCE0_RGB_ARB; src1_enum = GL_SOURCE1_RGB_ARB; src2_enum = GL_SOURCE2_RGB_ARB; operand0_enum = GL_OPERAND0_RGB_ARB; operand1_enum = GL_OPERAND1_RGB_ARB; operand2_enum = GL_OPERAND2_RGB_ARB; // cache current combiner mCurrColorOp = op; mCurrColorSrc1 = src1; mCurrColorSrc2 = src2; } switch(op) { case TBO_REPLACE: // Slightly special syntax (no second sources), just set all and return. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); (isAlpha) ? setAlphaScale(1) : setColorScale(1); return; case TBO_MULT: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); break; case TBO_MULT_X2: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); scale_amount = 2; break; case TBO_MULT_X4: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_MODULATE); scale_amount = 4; break; case TBO_ADD: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD); break; case TBO_ADD_SIGNED: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_ADD_SIGNED_ARB); break; case TBO_SUBTRACT: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_SUBTRACT_ARB); break; case TBO_LERP_VERT_ALPHA: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); break; case TBO_LERP_TEX_ALPHA: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); break; case TBO_LERP_PREV_ALPHA: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PREVIOUS_ARB); glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); break; case TBO_LERP_CONST_ALPHA: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_CONSTANT_ARB); glTexEnvi(GL_TEXTURE_ENV, operand2_enum, GL_SRC_ALPHA); break; case TBO_LERP_VERT_COLOR: glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, src2_enum, GL_PRIMARY_COLOR_ARB); glTexEnvi(GL_TEXTURE_ENV, operand2_enum, (isAlpha) ? GL_SRC_ALPHA : GL_SRC_COLOR); break; default: llwarns << "Unknown eTextureBlendOp: " << op << ". Setting op to replace." << llendl; // Slightly special syntax (no second sources), just set all and return. glTexEnvi(GL_TEXTURE_ENV, comb_enum, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); (isAlpha) ? setAlphaScale(1) : setColorScale(1); return; } // Set sources, operands, and scale accordingly glTexEnvi(GL_TEXTURE_ENV, src0_enum, source1); glTexEnvi(GL_TEXTURE_ENV, operand0_enum, operand1); glTexEnvi(GL_TEXTURE_ENV, src1_enum, source2); glTexEnvi(GL_TEXTURE_ENV, operand1_enum, operand2); (isAlpha) ? setAlphaScale(scale_amount) : setColorScale(scale_amount); }