SL-12069 Issues with bakes-on-mesh and alpha modes
parent
bb4d02446f
commit
5691d302ef
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include "llmaterial.h"
|
||||
|
||||
#include "../llrender/llglheaders.h"
|
||||
|
||||
/**
|
||||
* Materials cap parameters
|
||||
*/
|
||||
|
|
@ -105,6 +107,8 @@ LLMaterial::LLMaterial()
|
|||
, mSpecularLightExponent(LLMaterial::DEFAULT_SPECULAR_LIGHT_EXPONENT)
|
||||
, mEnvironmentIntensity(LLMaterial::DEFAULT_ENV_INTENSITY)
|
||||
, mDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
|
||||
, mDiffuseFormatPrimary(GL_RGBA)
|
||||
, mDiffuseBaked(false)
|
||||
, mAlphaMaskCutoff(0)
|
||||
{
|
||||
}
|
||||
|
|
@ -311,6 +315,20 @@ void LLMaterial::setEnvironmentIntensity(U8 intensity)
|
|||
mEnvironmentIntensity = intensity;
|
||||
}
|
||||
|
||||
U8 LLMaterial::getDiffuseAlphaModeRender() const
|
||||
{
|
||||
if (mDiffuseBaked
|
||||
|| mDiffuseFormatPrimary == GL_RGBA
|
||||
|| mDiffuseFormatPrimary == GL_ALPHA)
|
||||
{
|
||||
return mDiffuseAlphaMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DIFFUSE_ALPHA_MODE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
U8 LLMaterial::getDiffuseAlphaMode() const
|
||||
{
|
||||
return mDiffuseAlphaMode;
|
||||
|
|
@ -321,6 +339,26 @@ void LLMaterial::setDiffuseAlphaMode(U8 alpha_mode)
|
|||
mDiffuseAlphaMode = alpha_mode;
|
||||
}
|
||||
|
||||
U32 LLMaterial::getDiffuseFormatPrimary() const
|
||||
{
|
||||
return mDiffuseFormatPrimary;
|
||||
}
|
||||
|
||||
void LLMaterial::setDiffuseFormatPrimary(U32 format_primary)
|
||||
{
|
||||
mDiffuseFormatPrimary = format_primary;
|
||||
}
|
||||
|
||||
bool LLMaterial::getIsDiffuseBaked() const
|
||||
{
|
||||
return mDiffuseBaked;
|
||||
}
|
||||
|
||||
void LLMaterial::setDiffuseBaked(bool baked)
|
||||
{
|
||||
mDiffuseBaked = baked;
|
||||
}
|
||||
|
||||
U8 LLMaterial::getAlphaMaskCutoff() const
|
||||
{
|
||||
return mAlphaMaskCutoff;
|
||||
|
|
@ -437,7 +475,7 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode)
|
|||
}
|
||||
else
|
||||
{
|
||||
ret = getDiffuseAlphaMode();
|
||||
ret = getDiffuseAlphaModeRender();
|
||||
}
|
||||
|
||||
llassert(ret < SHADER_COUNT);
|
||||
|
|
|
|||
|
|
@ -115,8 +115,17 @@ public:
|
|||
void setSpecularLightExponent(U8 exponent);
|
||||
U8 getEnvironmentIntensity() const;
|
||||
void setEnvironmentIntensity(U8 intensity);
|
||||
|
||||
// getDiffuseAlphaModeRender takes into account if image supports alpha
|
||||
// and returns value apropriate for render
|
||||
// getDiffuseAlphaMode() returns value as is
|
||||
U8 getDiffuseAlphaModeRender() const;
|
||||
U8 getDiffuseAlphaMode() const;
|
||||
void setDiffuseAlphaMode(U8 alpha_mode);
|
||||
U32 getDiffuseFormatPrimary() const;
|
||||
void setDiffuseFormatPrimary(U32 format_primary);
|
||||
bool getIsDiffuseBaked() const;
|
||||
void setDiffuseBaked(bool baked);
|
||||
U8 getAlphaMaskCutoff() const;
|
||||
void setAlphaMaskCutoff(U8 cutoff);
|
||||
|
||||
|
|
@ -147,6 +156,8 @@ protected:
|
|||
U8 mSpecularLightExponent;
|
||||
U8 mEnvironmentIntensity;
|
||||
U8 mDiffuseAlphaMode;
|
||||
U32 mDiffuseFormatPrimary; // value from texture, LLGLenum, is not included in fromLLSD/asLLSD
|
||||
bool mDiffuseBaked; // is not included in fromLLSD/asLLSD
|
||||
U8 mAlphaMaskCutoff;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2120,7 +2120,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
|
||||
if (mat)
|
||||
{
|
||||
switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaMode()))
|
||||
switch (LLMaterial::eDiffuseAlphaMode(mat->getDiffuseAlphaModeRender()))
|
||||
{
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
|
||||
{
|
||||
|
|
@ -2258,7 +2258,7 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
|
||||
sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);
|
||||
|
||||
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
F32 cutoff = mat->getAlphaMaskCutoff()/255.f;
|
||||
sVertexProgram->setMinimumAlpha(cutoff);
|
||||
|
|
|
|||
|
|
@ -1165,7 +1165,7 @@ bool LLFace::canRenderAsMask()
|
|||
}
|
||||
|
||||
LLMaterial* mat = te->getMaterialParams();
|
||||
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
|
||||
if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1412,7 +1412,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (!mat || mat->getDiffuseAlphaModeRender() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
shiny_in_alpha = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4880,22 +4880,78 @@ void LLViewerObject::refreshBakeTexture()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerObject::updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture)
|
||||
{
|
||||
// Objects getting non-alpha texture and alpha mask can result in graphical bugs, like white or red alphas.
|
||||
// To resolve the issue this function provides image format to material and based on format material's
|
||||
// getDiffuseAlphaModeRender() function will decide what value to provide to render
|
||||
//
|
||||
// Unfortunately LLMaterial has no access to diffuse image, so we have to set this data in LLViewerObject
|
||||
// regardles of object being used/seen or frequency of image-updates.
|
||||
mat->setDiffuseBaked(baked_texture);
|
||||
|
||||
if (!baked_texture)
|
||||
{
|
||||
if (imagep->isMissingAsset())
|
||||
{
|
||||
mat->setDiffuseFormatPrimary(0);
|
||||
}
|
||||
else if (0 == imagep->getPrimaryFormat())
|
||||
{
|
||||
// We don't have information about this texture, wait for it
|
||||
mWaitingTextureInfo.insert(uuid_material_mmap_t::value_type(imagep->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
|
||||
// Temporary assume RGBA image
|
||||
mat->setDiffuseFormatPrimary(GL_RGBA);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat->setDiffuseFormatPrimary(imagep->getPrimaryFormat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLViewerObject::setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep)
|
||||
{
|
||||
LLUUID new_id = imagep->getID();
|
||||
S32 retval = LLPrimitive::setTETexture(te, new_id);
|
||||
|
||||
LLTextureEntry* tep = getTE(te);
|
||||
LLUUID old_image_id = tep->getID();
|
||||
|
||||
LLViewerTexture* baked_texture = getBakedTextureForMagicId(new_id);
|
||||
mTEImages[te] = baked_texture ? baked_texture : imagep;
|
||||
updateAvatarMeshVisibility(new_id, old_image_id);
|
||||
|
||||
LLMaterial* mat = tep->getMaterialParams();
|
||||
if (mat)
|
||||
{
|
||||
// Don't update format from texture (and don't shedule one) if material has no alpha mode set,
|
||||
// just assume RGBA format, format will get updated with setTEMaterialParams call if mode changes
|
||||
if (mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
|
||||
{
|
||||
bool baked = baked_texture != NULL;
|
||||
updateDiffuseMatParams(te, mat, imagep, baked);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat->setDiffuseFormatPrimary(GL_RGBA);
|
||||
}
|
||||
}
|
||||
|
||||
setChanged(TEXTURE);
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
gPipeline.markTextured(mDrawable);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
|
||||
{
|
||||
if (mTEImages[te] != imagep)
|
||||
{
|
||||
LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null;
|
||||
|
||||
LLPrimitive::setTETexture(te, imagep->getID());
|
||||
|
||||
LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID());
|
||||
mTEImages[te] = baked_texture ? baked_texture : imagep;
|
||||
updateAvatarMeshVisibility(imagep->getID(), old_image_id);
|
||||
setChanged(TEXTURE);
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
gPipeline.markTextured(mDrawable);
|
||||
}
|
||||
setDiffuseImageAndParams(te, imagep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4907,15 +4963,7 @@ S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
|
|||
if (uuid != getTE(te)->getID() ||
|
||||
uuid == LLUUID::null)
|
||||
{
|
||||
retval = LLPrimitive::setTETexture(te, uuid);
|
||||
LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid);
|
||||
mTEImages[te] = baked_texture ? baked_texture : image;
|
||||
updateAvatarMeshVisibility(uuid,old_image_id);
|
||||
setChanged(TEXTURE);
|
||||
if (mDrawable.notNull())
|
||||
{
|
||||
gPipeline.markTextured(mDrawable);
|
||||
}
|
||||
retval = setDiffuseImageAndParams(te, image);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -5210,6 +5258,29 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (pMaterialParams.notNull()
|
||||
&& pMaterialParams->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
|
||||
{
|
||||
// Don't update if no alpha is set. If alpha changes, this function will run again,
|
||||
// no point in sheduling additional texture callbacks (in updateDiffuseMatParams)
|
||||
LLTextureEntry* tex_entry = getTE(te);
|
||||
bool is_baked = tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID());
|
||||
|
||||
LLViewerTexture *img_diffuse = getTEImage(te);
|
||||
llassert(NULL != img_diffuse);
|
||||
|
||||
if (NULL != img_diffuse)
|
||||
{
|
||||
// Will modify alpha mask provided to renderer to fit image
|
||||
updateDiffuseMatParams(te, pMaterialParams.get(), img_diffuse, is_baked);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLMaterial *mat = pMaterialParams.get(); // to avoid const
|
||||
mat->setDiffuseFormatPrimary(0);
|
||||
}
|
||||
}
|
||||
|
||||
retval = LLPrimitive::setTEMaterialParams(te, pMaterialParams);
|
||||
LL_DEBUGS("Material") << "Changing material params for te " << (S32)te
|
||||
<< ", object " << mID
|
||||
|
|
@ -5222,6 +5293,84 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
|
|||
return retval;
|
||||
}
|
||||
|
||||
bool LLViewerObject::notifyAboutCreatingTexture(LLViewerTexture *texture)
|
||||
{
|
||||
// Confirmation about texture creation, check wait-list
|
||||
// and make changes, or return false
|
||||
|
||||
std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
|
||||
|
||||
bool refresh_materials = false;
|
||||
|
||||
// RGB textures without alpha channels won't work right with alpha,
|
||||
// we provide format to material for material to decide when to drop alpha
|
||||
for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it)
|
||||
{
|
||||
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
|
||||
if (cur_material.notNull()
|
||||
&& LLRender::DIFFUSE_MAP == range_it->second.map)
|
||||
{
|
||||
U32 format = texture->getPrimaryFormat();
|
||||
if (format != cur_material->getDiffuseFormatPrimary())
|
||||
{
|
||||
cur_material->setDiffuseFormatPrimary(format);
|
||||
refresh_materials = true;
|
||||
}
|
||||
}
|
||||
} //for
|
||||
|
||||
if (refresh_materials)
|
||||
{
|
||||
LLViewerObject::refreshMaterials();
|
||||
}
|
||||
|
||||
//clear wait-list
|
||||
mWaitingTextureInfo.erase(range.first, range.second);
|
||||
|
||||
return refresh_materials;
|
||||
}
|
||||
|
||||
bool LLViewerObject::notifyAboutMissingAsset(LLViewerTexture *texture)
|
||||
{
|
||||
// When waiting information about texture it turned out to be missing.
|
||||
// Confirm the state, update values accordingly
|
||||
std::pair<uuid_material_mmap_t::iterator, uuid_material_mmap_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
|
||||
if (range.first == range.second) return false;
|
||||
|
||||
bool refresh_materials = false;
|
||||
|
||||
for (uuid_material_mmap_t::iterator range_it = range.first; range_it != range.second; ++range_it)
|
||||
{
|
||||
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
|
||||
if (cur_material.isNull())
|
||||
continue;
|
||||
|
||||
if (range_it->second.map == LLRender::DIFFUSE_MAP)
|
||||
{
|
||||
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
|
||||
if (cur_material.notNull()
|
||||
&& LLRender::DIFFUSE_MAP == range_it->second.map)
|
||||
{
|
||||
if (0 != cur_material->getDiffuseFormatPrimary())
|
||||
{
|
||||
cur_material->setDiffuseFormatPrimary(0);
|
||||
refresh_materials = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //for
|
||||
|
||||
if (refresh_materials)
|
||||
{
|
||||
LLViewerObject::refreshMaterials();
|
||||
}
|
||||
|
||||
//clear wait-list
|
||||
mWaitingTextureInfo.erase(range.first, range.second);
|
||||
|
||||
return refresh_materials;
|
||||
}
|
||||
|
||||
void LLViewerObject::refreshMaterials()
|
||||
{
|
||||
setChanged(TEXTURE);
|
||||
|
|
|
|||
|
|
@ -768,7 +768,12 @@ protected:
|
|||
void unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_id, bool legacy);
|
||||
void deleteParticleSource();
|
||||
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
|
||||
|
||||
|
||||
// Helper function to modify alpha mask provided to render according to image (ex: RGB image will drop alpha mask)
|
||||
void updateDiffuseMatParams(const U8 te, LLMaterial* mat, LLViewerTexture *imagep, bool baked_texture);
|
||||
// Shared part of code from setTEImage and setTETextureCore
|
||||
S32 setDiffuseImageAndParams(const U8 te, LLViewerTexture *imagep);
|
||||
|
||||
private:
|
||||
void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
|
||||
void deleteTEImages(); // correctly deletes list of images
|
||||
|
|
@ -901,10 +906,27 @@ public:
|
|||
|
||||
LLJointRiggingInfoTab mJointRiggingInfoTab;
|
||||
|
||||
bool notifyAboutCreatingTexture(LLViewerTexture *texture);
|
||||
bool notifyAboutMissingAsset(LLViewerTexture *texture);
|
||||
|
||||
private:
|
||||
LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
|
||||
EObjectUpdateType mLastUpdateType;
|
||||
BOOL mLastUpdateCached;
|
||||
|
||||
struct material_info
|
||||
{
|
||||
LLRender::eTexIndex map;
|
||||
U8 te;
|
||||
|
||||
material_info(LLRender::eTexIndex map_, U8 te_)
|
||||
: map(map_)
|
||||
, te(te_)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef std::multimap<LLUUID, material_info> uuid_material_mmap_t;
|
||||
uuid_material_mmap_t mWaitingTextureInfo;
|
||||
};
|
||||
|
||||
///////////////////
|
||||
|
|
|
|||
|
|
@ -2290,243 +2290,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
|
|||
return res;
|
||||
}
|
||||
|
||||
bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
|
||||
{ //Ok, here we have confirmation about texture creation, check our wait-list
|
||||
//and make changes, or return false
|
||||
|
||||
std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
|
||||
|
||||
typedef std::map<U8, LLMaterialPtr> map_te_material;
|
||||
map_te_material new_material;
|
||||
|
||||
for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
|
||||
{
|
||||
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
|
||||
|
||||
//here we just interesting in DIFFUSE_MAP only!
|
||||
if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
|
||||
{ //ok let's check the diffuse mode
|
||||
switch(cur_material->getDiffuseAlphaMode())
|
||||
{
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
|
||||
{ //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
|
||||
|
||||
LLMaterialPtr mat = NULL;
|
||||
map_te_material::iterator it = new_material.find(range_it->second.te);
|
||||
if(new_material.end() == it) {
|
||||
mat = new LLMaterial(cur_material->asLLSD());
|
||||
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
|
||||
} else {
|
||||
mat = it->second;
|
||||
}
|
||||
|
||||
mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
|
||||
|
||||
} break;
|
||||
} //switch
|
||||
} //if
|
||||
} //for
|
||||
|
||||
//setup new materials
|
||||
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
|
||||
{
|
||||
LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
|
||||
LLViewerObject::setTEMaterialParams(it->first, it->second);
|
||||
}
|
||||
|
||||
//clear wait-list
|
||||
mWaitingTextureInfo.erase(range.first, range.second);
|
||||
|
||||
return 0 != new_material.size();
|
||||
}
|
||||
|
||||
bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
|
||||
{ //Ok, here if we wait information about texture and it's missing
|
||||
//then depending from the texture map (diffuse, normal, or specular)
|
||||
//make changes in material and confirm it. If not return false.
|
||||
std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
|
||||
if(range.first == range.second) return false;
|
||||
|
||||
typedef std::map<U8, LLMaterialPtr> map_te_material;
|
||||
map_te_material new_material;
|
||||
|
||||
for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
|
||||
{
|
||||
LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
|
||||
if (cur_material.isNull())
|
||||
continue;
|
||||
|
||||
switch(range_it->second.map)
|
||||
{
|
||||
case LLRender::DIFFUSE_MAP:
|
||||
{
|
||||
if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
|
||||
{ //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
|
||||
LLMaterialPtr mat = NULL;
|
||||
map_te_material::iterator it = new_material.find(range_it->second.te);
|
||||
if(new_material.end() == it) {
|
||||
mat = new LLMaterial(cur_material->asLLSD());
|
||||
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
|
||||
} else {
|
||||
mat = it->second;
|
||||
}
|
||||
|
||||
mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
|
||||
}
|
||||
} break;
|
||||
case LLRender::NORMAL_MAP:
|
||||
{ //missing texture => reset material texture id
|
||||
LLMaterialPtr mat = NULL;
|
||||
map_te_material::iterator it = new_material.find(range_it->second.te);
|
||||
if(new_material.end() == it) {
|
||||
mat = new LLMaterial(cur_material->asLLSD());
|
||||
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
|
||||
} else {
|
||||
mat = it->second;
|
||||
}
|
||||
|
||||
mat->setNormalID(LLUUID::null);
|
||||
} break;
|
||||
case LLRender::SPECULAR_MAP:
|
||||
{ //missing texture => reset material texture id
|
||||
LLMaterialPtr mat = NULL;
|
||||
map_te_material::iterator it = new_material.find(range_it->second.te);
|
||||
if(new_material.end() == it) {
|
||||
mat = new LLMaterial(cur_material->asLLSD());
|
||||
new_material.insert(map_te_material::value_type(range_it->second.te, mat));
|
||||
} else {
|
||||
mat = it->second;
|
||||
}
|
||||
|
||||
mat->setSpecularID(LLUUID::null);
|
||||
} break;
|
||||
case LLRender::NUM_TEXTURE_CHANNELS:
|
||||
//nothing to do, make compiler happy
|
||||
break;
|
||||
} //switch
|
||||
} //for
|
||||
|
||||
//setup new materials
|
||||
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
|
||||
{
|
||||
LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
|
||||
LLViewerObject::setTEMaterialParams(it->first, it->second);
|
||||
}
|
||||
|
||||
//clear wait-list
|
||||
mWaitingTextureInfo.erase(range.first, range.second);
|
||||
|
||||
return 0 != new_material.size();
|
||||
}
|
||||
|
||||
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
|
||||
{
|
||||
LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
|
||||
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
|
||||
|
||||
if(pMaterialParams)
|
||||
{ //check all of them according to material settings
|
||||
|
||||
LLViewerTexture *img_diffuse = getTEImage(te);
|
||||
LLViewerTexture *img_normal = getTENormalMap(te);
|
||||
LLViewerTexture *img_specular = getTESpecularMap(te);
|
||||
|
||||
llassert(NULL != img_diffuse);
|
||||
|
||||
LLMaterialPtr new_material = NULL;
|
||||
|
||||
//diffuse
|
||||
if(NULL != img_diffuse)
|
||||
{ //guard
|
||||
if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
|
||||
{ //ok here we don't have information about texture, let's belief and leave material settings
|
||||
//but we remember this case
|
||||
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bSetDiffuseNone = false;
|
||||
if(img_diffuse->isMissingAsset())
|
||||
{
|
||||
bSetDiffuseNone = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(pMaterialParams->getDiffuseAlphaMode())
|
||||
{
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
|
||||
case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
|
||||
{ //all of them modes available only for 32 bit textures
|
||||
LLTextureEntry* tex_entry = getTE(te);
|
||||
bool bIsBakedImageId = false;
|
||||
if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()))
|
||||
{
|
||||
bIsBakedImageId = true;
|
||||
}
|
||||
if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId)
|
||||
{
|
||||
bSetDiffuseNone = true;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} //else
|
||||
|
||||
|
||||
if(bSetDiffuseNone)
|
||||
{ //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
|
||||
new_material = new LLMaterial(pMaterialParams->asLLSD());
|
||||
new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//normal
|
||||
if(LLUUID::null != pMaterialParams->getNormalID())
|
||||
{
|
||||
if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
|
||||
{
|
||||
if(!new_material) {
|
||||
new_material = new LLMaterial(pMaterialParams->asLLSD());
|
||||
}
|
||||
new_material->setNormalID(LLUUID::null);
|
||||
}
|
||||
else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
|
||||
{ //ok here we don't have information about texture, let's belief and leave material settings
|
||||
//but we remember this case
|
||||
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//specular
|
||||
if(LLUUID::null != pMaterialParams->getSpecularID())
|
||||
{
|
||||
if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
|
||||
{
|
||||
if(!new_material) {
|
||||
new_material = new LLMaterial(pMaterialParams->asLLSD());
|
||||
}
|
||||
new_material->setSpecularID(LLUUID::null);
|
||||
}
|
||||
else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
|
||||
{ //ok here we don't have information about texture, let's belief and leave material settings
|
||||
//but we remember this case
|
||||
mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
|
||||
}
|
||||
}
|
||||
|
||||
if(new_material) {
|
||||
pMaterial = new_material;
|
||||
LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial);
|
||||
|
||||
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res
|
||||
LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
|
||||
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
|
||||
<< LL_ENDL;
|
||||
setChanged(ALL_CHANGED);
|
||||
|
|
@ -4593,7 +4361,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
|
|||
LLMaterial* mat = te->getMaterialParams();
|
||||
if (mat)
|
||||
{
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
U8 mode = mat->getDiffuseAlphaModeRender();
|
||||
|
||||
if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE
|
||||
|| mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE
|
||||
|
|
@ -5239,7 +5007,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
|||
}
|
||||
|
||||
draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
|
||||
draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
|
||||
draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaModeRender();
|
||||
draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
|
||||
}
|
||||
else
|
||||
|
|
@ -5601,7 +5369,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
|
||||
if (mat && LLPipeline::sRenderDeferred)
|
||||
{
|
||||
U8 alpha_mode = mat->getDiffuseAlphaMode();
|
||||
U8 alpha_mode = mat->getDiffuseAlphaModeRender();
|
||||
|
||||
bool is_alpha = type == LLDrawPool::POOL_ALPHA &&
|
||||
(alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND ||
|
||||
|
|
@ -5630,7 +5398,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
else if (mat)
|
||||
{
|
||||
bool is_alpha = type == LLDrawPool::POOL_ALPHA;
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
U8 mode = mat->getDiffuseAlphaModeRender();
|
||||
bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
|
||||
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
|
||||
|
||||
|
|
@ -6528,7 +6296,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
bool can_be_shiny = true;
|
||||
if (mat)
|
||||
{
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
U8 mode = mat->getDiffuseAlphaModeRender();
|
||||
can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
|
||||
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
|
||||
}
|
||||
|
|
@ -6550,7 +6318,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
//
|
||||
if (te->getFullbright())
|
||||
{
|
||||
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
if (opaque)
|
||||
{
|
||||
|
|
@ -6635,7 +6403,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
}
|
||||
else if (mat)
|
||||
{
|
||||
U8 mode = mat->getDiffuseAlphaMode();
|
||||
U8 mode = mat->getDiffuseAlphaModeRender();
|
||||
|
||||
is_alpha = (is_alpha || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND));
|
||||
|
||||
|
|
@ -6734,7 +6502,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
}
|
||||
else if (fullbright || bake_sunlight)
|
||||
{ //fullbright
|
||||
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{
|
||||
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
|
||||
}
|
||||
|
|
@ -6756,7 +6524,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
|
|||
else
|
||||
{ //all around simple
|
||||
llassert(mask & LLVertexBuffer::MAP_NORMAL);
|
||||
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
if (mat && mat->getDiffuseAlphaModeRender() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
|
||||
{ //material alpha mask can be respected in non-deferred
|
||||
registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -441,26 +441,6 @@ protected:
|
|||
static S32 sNumLODChanges;
|
||||
|
||||
friend class LLVolumeImplFlexible;
|
||||
|
||||
public:
|
||||
bool notifyAboutCreatingTexture(LLViewerTexture *texture);
|
||||
bool notifyAboutMissingAsset(LLViewerTexture *texture);
|
||||
|
||||
private:
|
||||
struct material_info
|
||||
{
|
||||
LLRender::eTexIndex map;
|
||||
U8 te;
|
||||
|
||||
material_info(LLRender::eTexIndex map_, U8 te_)
|
||||
: map(map_)
|
||||
, te(te_)
|
||||
{}
|
||||
};
|
||||
|
||||
typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
|
||||
mmap_UUID_MAP_t mWaitingTextureInfo;
|
||||
|
||||
};
|
||||
|
||||
#endif // LL_LLVOVOLUME_H
|
||||
|
|
|
|||
|
|
@ -1677,7 +1677,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
|
|||
|
||||
if (alpha && mat)
|
||||
{
|
||||
switch (mat->getDiffuseAlphaMode())
|
||||
switch (mat->getDiffuseAlphaModeRender())
|
||||
{
|
||||
case 1:
|
||||
alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
|
||||
|
|
|
|||
Loading…
Reference in New Issue