123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- /**
- * @file llfetchedgltfmaterial.cpp
- *
- * $LicenseInfo:firstyear=2022&license=viewergpl$
- *
- * Copyright (c) 2022, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llfetchedgltfmaterial.h"
- #include "llshadermgr.h"
- #include "llgltfmaterialpreview.h"
- #include "lllocalbitmaps.h"
- #include "llpipeline.h"
- #include "llviewertexturelist.h"
- LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
- {
- LLGLTFMaterial::operator=(rhs);
- mBaseColorTexture = rhs.mBaseColorTexture;
- mNormalTexture = rhs.mNormalTexture;
- mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture;
- mEmissiveTexture = rhs.mEmissiveTexture;
- return *this;
- }
- void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_texp, F32 vsize)
- {
- if (!gUsePBRShaders)
- {
- return;
- }
- LLGLSLShader* shaderp = LLGLSLShader::sCurBoundShaderPtr;
- if (!shaderp) // Paranoia
- {
- llwarns << "No bound shader !" << llendl;
- return;
- }
- // Override emissive and base color textures with media texture if present
- LLViewerTexture* basecolorp;
- LLViewerTexture* emissivep;
- if (media_texp)
- {
- basecolorp = emissivep = media_texp;
- }
- else
- {
- basecolorp = mBaseColorTexture;
- emissivep = mEmissiveTexture;
- }
- // glTF 2.0 Specification 3.9.4. Alpha Coverage: mAlphaCutoff is only valid
- // for LLGLTFMaterial::ALPHA_MODE_MASK.
- F32 min_alpha = -1.f;
- bool is_alpha_mask = mAlphaMode == ALPHA_MODE_MASK;
- if (is_alpha_mask || !LLPipeline::sShadowRender)
- {
- if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
- {
- min_alpha = mAlphaCutoff;
- }
- shaderp->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
- }
- if (basecolorp)
- {
- shaderp->bindTexture(LLShaderMgr::DIFFUSE_MAP, basecolorp);
- basecolorp->addTextureStats(vsize);
- }
- else
- {
- shaderp->bindTexture(LLShaderMgr::DIFFUSE_MAP,
- LLViewerFetchedTexture::sWhiteImagep);
- }
- static F32 p_basecol[8], p_normal[8], p_roughness[8], p_emissive[8];
- mTextureTransform[BASECOLIDX].getPacked(p_basecol);
- shaderp->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2,
- p_basecol);
- if (LLPipeline::sShadowRender)
- {
- return; // Nothing else to do.
- }
- if (mNormalTexture.notNull() && mNormalTexture->getDiscardLevel() <= 4)
- {
- shaderp->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture);
- mNormalTexture->addTextureStats(vsize);
- }
- else
- {
- shaderp->bindTexture(LLShaderMgr::BUMP_MAP,
- LLViewerFetchedTexture::sFlatNormalImagep);
- }
- if (mMetallicRoughnessTexture.notNull())
- {
- // PBR linear packed Occlusion, Roughness, Metal.
- shaderp->bindTexture(LLShaderMgr::SPECULAR_MAP,
- mMetallicRoughnessTexture);
- mMetallicRoughnessTexture->addTextureStats(vsize);
- }
- else
- {
- shaderp->bindTexture(LLShaderMgr::SPECULAR_MAP,
- LLViewerFetchedTexture::sWhiteImagep);
- }
- if (emissivep)
- {
- // PBR sRGB Emissive
- shaderp->bindTexture(LLShaderMgr::EMISSIVE_MAP, emissivep);
- emissivep->addTextureStats(vsize);
- }
- else
- {
- shaderp->bindTexture(LLShaderMgr::EMISSIVE_MAP,
- LLViewerFetchedTexture::sWhiteImagep);
- }
- // Note: base color factor is baked into vertex stream.
- shaderp->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor);
- shaderp->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
- shaderp->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
- mTextureTransform[NORMALIDX].getPacked(p_normal);
- shaderp->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, p_normal);
- mTextureTransform[MROUGHIDX].getPacked(p_roughness);
- shaderp->uniform4fv(LLShaderMgr::TEXTURE_ROUGHNESS_TRANSFORM, 2,
- p_roughness);
- mTextureTransform[EMISSIVEIDX].getPacked(p_emissive);
- shaderp->uniform4fv(LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM, 2,
- p_emissive);
- }
- void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> cb)
- {
- if (cb)
- {
- if (!mFetching)
- {
- cb();
- return;
- }
- mCompleteCallbacks.emplace_back(cb);
- }
- }
- void LLFetchedGLTFMaterial::materialComplete(bool success)
- {
- mFetching = false;
- mFetchSuccess = success;
- for (U32 i = 0, count = mCompleteCallbacks.size(); i < count; ++i)
- {
- mCompleteCallbacks[i]();
- }
- mCompleteCallbacks.clear();
- }
- static LLViewerFetchedTexture* fetch_texture(const LLUUID& id)
- {
- if (id.isNull())
- {
- return NULL;
- }
- LLViewerFetchedTexture* texp =
- LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true,
- LLGLTexture::BOOST_NONE,
- LLViewerTexture::LOD_TEXTURE);
- if (texp) // Paranoia
- {
- texp->addTextureStats(64.f * 64.f);
- }
- return texp;
- }
- //virtual
- bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id,
- const LLUUID& old_id,
- const LLUUID& new_id)
- {
- bool seen = false;
- if (mTextureId[BASECOLIDX] == old_id)
- {
- mTextureId[BASECOLIDX] = new_id;
- mBaseColorTexture = fetch_texture(new_id);
- seen = true;
- }
- if (mTextureId[NORMALIDX] == old_id)
- {
- mTextureId[NORMALIDX] = new_id;
- mNormalTexture = fetch_texture(new_id);
- seen = true;
- }
- if (mTextureId[MROUGHIDX] == old_id)
- {
- mTextureId[MROUGHIDX] = new_id;
- mMetallicRoughnessTexture = fetch_texture(new_id);
- seen = true;
- }
- if (mTextureId[EMISSIVEIDX] == old_id)
- {
- mTextureId[EMISSIVEIDX] = new_id;
- mEmissiveTexture = fetch_texture(new_id);
- seen = true;
- }
- for (U32 i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
- {
- if (mTextureId[i] == new_id)
- {
- seen = true;
- }
- }
- if (seen)
- {
- mTrackingIdToLocalTexture[tracking_id] = new_id;
- }
- else
- {
- mTrackingIdToLocalTexture.erase(tracking_id);
- }
- return seen;
- }
- //virtual
- void LLFetchedGLTFMaterial::addTextureEntry(LLTextureEntry* tep)
- {
- mTextureEntries.insert(tep);
- }
- //virtual
- void LLFetchedGLTFMaterial::removeTextureEntry(LLTextureEntry* tep)
- {
- mTextureEntries.erase(tep);
- }
- //virtual
- void LLFetchedGLTFMaterial::updateTextureTracking()
- {
- if (!mTrackingIdToLocalTexture.empty())
- {
- for (local_tex_map_t::const_iterator
- it = mTrackingIdToLocalTexture.begin(),
- end = mTrackingIdToLocalTexture.end();
- it != end; ++it)
- {
- LLLocalBitmap::associateGLTFMaterial(it->first, this);
- }
- }
- }
- LLViewerTexture* LLFetchedGLTFMaterial::getPreview()
- {
- if (mPreview.isNull())
- {
- mPreview = LLGLTFPreviewTexture::getPreview(this);
- }
- return mPreview.get();
- }
- // ----------------------------------------------------------------------------
- // These are functions used in the llgltf library to deal with fetched
- // materials without knowing anything about them excepted that they derive from
- // the parent LLGLTFMaterial class... HB
- LLGLTFMaterial* create_fetch_material()
- {
- return new LLFetchedGLTFMaterial();
- }
- void bind_fetched_material(LLGLTFMaterial* matp)
- {
- LLFetchedGLTFMaterial* fmatp = NULL;
- if (matp)
- {
- fmatp = dynamic_cast<LLFetchedGLTFMaterial*>(matp);
- }
- if (!fmatp)
- {
- static LLFetchedGLTFMaterial sDefault;
- fmatp = &sDefault;
- }
- constexpr F32 VSIZE_DEFAULT = 256.f * 256.f;
- fmatp->bind(NULL, VSIZE_DEFAULT);
- }
- // For the new implementation of the llgltf library (WIP).
- // Merely implemented here because two of them reuse fetch_texture() which we
- // need in this module anyway, and also because this module uses LLLocalBitmap
- // already. *TODO: move to llgltfscenemanager.h/cpp ? HB
- LLGLTexture* gl_texture_from_fetched(const LLUUID& id)
- {
- return fetch_texture(id);
- }
- LLGLTexture* gl_texture_from_local_file(const std::string& filename)
- {
- if (!LLFile::exists(filename))
- {
- return NULL;
- }
- LLLocalBitmap* bitmapp = LLLocalBitmap::addUnit(filename);
- if (!bitmapp)
- {
- return NULL;
- }
- return fetch_texture(bitmapp->getWorldID());
- }
- LLGLTexture* gl_texture_from_memory(U8* datap, S32 size,
- const std::string& mime_type)
- {
- if (!datap || size <= 0)
- {
- return NULL;
- }
- LLPointer<LLImageFormatted> imagep =
- LLImageFormatted::createFromMimeType(mime_type);
- if (!imagep)
- {
- return NULL;
- }
- U8* image_datap = imagep->allocateData(size);
- memcpy((void*)image_datap, (void*)datap, (size_t)size);
- if (!imagep->updateData())
- {
- return NULL;
- }
- LLPointer<LLImageRaw> raw_imagep = new LLImageRaw();
- imagep->decode(raw_imagep);
- if (raw_imagep.isNull())
- {
- return NULL;
- }
- LLViewerFetchedTexture* texp = new LLViewerFetchedTexture(raw_imagep,
- FTT_LOCAL_FILE,
- true);
- texp->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
- texp->dontDiscard();
- #if !LL_IMPLICIT_SETNODELETE
- texp->setNoDelete();
- #endif
- return texp;
- }
|