SL-20606: Full GLTF material preview. Works for most materials.
parent
c2a30057f8
commit
2f18d74f9a
|
|
@ -65,7 +65,6 @@ class LLCamera
|
|||
: public LLCoordFrame
|
||||
{
|
||||
public:
|
||||
|
||||
LLCamera(const LLCamera& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
|
|
|
|||
|
|
@ -1319,6 +1319,10 @@ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, U32 index,
|
|||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index, count);
|
||||
}
|
||||
bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector4a>& strider, U32 index, S32 count)
|
||||
{
|
||||
return VertexBufferStrider<LLVector4a, TYPE_NORMAL>::get(*this, strider, index, count);
|
||||
}
|
||||
bool LLVertexBuffer::getTangentStrider(LLStrider<LLVector3>& strider, U32 index, S32 count)
|
||||
{
|
||||
return VertexBufferStrider<LLVector3,TYPE_TANGENT>::get(*this, strider, index, count);
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public:
|
|||
bool getTexCoord1Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getTexCoord2Strider(LLStrider<LLVector2>& strider, U32 index=0, S32 count = -1);
|
||||
bool getNormalStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
|
||||
bool getNormalStrider(LLStrider<LLVector4a>& strider, U32 index = 0, S32 count = -1);
|
||||
bool getTangentStrider(LLStrider<LLVector3>& strider, U32 index=0, S32 count = -1);
|
||||
bool getTangentStrider(LLStrider<LLVector4a>& strider, U32 index=0, S32 count = -1);
|
||||
bool getColorStrider(LLStrider<LLColor4U>& strider, U32 index=0, S32 count = -1);
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@ set(viewer_SOURCE_FILES
|
|||
llgiveinventory.cpp
|
||||
llglsandbox.cpp
|
||||
llgltfmateriallist.cpp
|
||||
llgltfmaterialpreviewmgr.cpp
|
||||
llgroupactions.cpp
|
||||
llgroupiconctrl.cpp
|
||||
llgrouplist.cpp
|
||||
|
|
@ -963,6 +964,7 @@ set(viewer_HEADER_FILES
|
|||
llgesturemgr.h
|
||||
llgiveinventory.h
|
||||
llgltfmateriallist.h
|
||||
llgltfmaterialpreviewmgr.h
|
||||
llgroupactions.h
|
||||
llgroupiconctrl.h
|
||||
llgrouplist.h
|
||||
|
|
|
|||
|
|
@ -37,7 +37,11 @@ void main()
|
|||
{
|
||||
vec4 diff = texture(diffuseRect, vary_fragcoord.xy);
|
||||
|
||||
#if 1
|
||||
frag_color = diff;
|
||||
#else
|
||||
frag_color = vec4(1,0,1,1);
|
||||
#endif
|
||||
|
||||
gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,13 +189,18 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD;
|
||||
LLRenderTarget& bake_target = gPipeline.mAuxillaryRT.deferredScreen;
|
||||
|
||||
if (use_fbo)
|
||||
{
|
||||
gPipeline.mBake.bindTarget();
|
||||
gPipeline.mBake.clear();
|
||||
}
|
||||
if (!bake_target.isComplete())
|
||||
{
|
||||
llassert(false);
|
||||
return FALSE;
|
||||
}
|
||||
llassert(bake_target.getWidth() >= LLPipeline::MAX_BAKE_WIDTH);
|
||||
llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH);
|
||||
|
||||
bake_target.bindTarget();
|
||||
bake_target.clear();
|
||||
|
||||
LLGLSLShader::unbind();
|
||||
LLVertexBuffer::unbind();
|
||||
|
|
@ -210,11 +215,14 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
LLViewerDynamicTexture *dynamicTexture = *iter;
|
||||
if (dynamicTexture->needsRender())
|
||||
{
|
||||
llassert(dynamicTexture->getFullWidth() <= LLPipeline::MAX_BAKE_WIDTH);
|
||||
llassert(dynamicTexture->getFullHeight() <= LLPipeline::MAX_BAKE_WIDTH);
|
||||
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
gDepthDirty = TRUE;
|
||||
|
||||
gGL.color4f(1,1,1,1);
|
||||
dynamicTexture->setBoundTarget(use_fbo ? &gPipeline.mBake : nullptr);
|
||||
dynamicTexture->setBoundTarget(&bake_target);
|
||||
dynamicTexture->preRender(); // Must be called outside of startRender()
|
||||
result = FALSE;
|
||||
if (dynamicTexture->render())
|
||||
|
|
@ -231,10 +239,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
|
|||
}
|
||||
}
|
||||
|
||||
if (use_fbo)
|
||||
{
|
||||
gPipeline.mBake.flush();
|
||||
}
|
||||
bake_target.flush();
|
||||
|
||||
gGL.flush();
|
||||
|
||||
|
|
|
|||
|
|
@ -254,55 +254,3 @@ void LLFetchedGLTFMaterial::materialComplete()
|
|||
materialCompleteCallbacks.clear();
|
||||
materialCompleteCallbacks.shrink_to_fit();
|
||||
}
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> LLFetchedGLTFMaterial::getUITexture()
|
||||
{
|
||||
if (mFetching)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto fetch_texture_for_ui = [](LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
|
||||
{
|
||||
if (id.notNull())
|
||||
{
|
||||
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
|
||||
{
|
||||
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
||||
if (obj)
|
||||
{
|
||||
LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
|
||||
img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
}
|
||||
}
|
||||
if (img)
|
||||
{
|
||||
img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
img->forceToSaveRawImage(0);
|
||||
}
|
||||
};
|
||||
|
||||
fetch_texture_for_ui(mBaseColorTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
|
||||
fetch_texture_for_ui(mNormalTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
|
||||
fetch_texture_for_ui(mMetallicRoughnessTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
|
||||
fetch_texture_for_ui(mEmissiveTexture, mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
|
||||
|
||||
if ((mBaseColorTexture && (mBaseColorTexture->getRawImageLevel() != 0)) ||
|
||||
(mNormalTexture && (mNormalTexture->getRawImageLevel() != 0)) ||
|
||||
(mMetallicRoughnessTexture && (mMetallicRoughnessTexture->getRawImageLevel() != 0)) ||
|
||||
(mEmissiveTexture && (mEmissiveTexture->getRawImageLevel() != 0)))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// *HACK: Use one of the PBR texture components as the preview texture for now
|
||||
mPreviewTexture = mBaseColorTexture;
|
||||
|
||||
return mPreviewTexture;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ public:
|
|||
|
||||
bool isFetching() const { return mFetching; }
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> getUITexture();
|
||||
|
||||
void addTextureEntry(LLTextureEntry* te) override;
|
||||
void removeTextureEntry(LLTextureEntry* te) override;
|
||||
virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override;
|
||||
|
|
@ -65,9 +63,6 @@ public:
|
|||
|
||||
std::set<LLTextureEntry*> mTextureEntires;
|
||||
|
||||
// Texture used for previewing the material in the UI
|
||||
LLPointer<LLViewerFetchedTexture> mPreviewTexture;
|
||||
|
||||
protected:
|
||||
// Lifetime management
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,501 @@
|
|||
/**
|
||||
* @file llgltfmaterialpreviewmgr.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llgltfmaterialpreviewmgr.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llenvironment.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llviewercamera.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewershadermgr.h"
|
||||
#include "llviewertexturelist.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvolumemgr.h"
|
||||
#include "pipeline.h"
|
||||
|
||||
LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr S32 FULLY_LOADED = 0;
|
||||
constexpr S32 NOT_LOADED = 99;
|
||||
};
|
||||
|
||||
LLGLTFPreviewTexture::MaterialLoadLevels::MaterialLoadLevels()
|
||||
{
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
levels[i] = NOT_LOADED;
|
||||
}
|
||||
}
|
||||
|
||||
S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i)
|
||||
{
|
||||
llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
|
||||
return levels[i];
|
||||
}
|
||||
|
||||
const S32& LLGLTFPreviewTexture::MaterialLoadLevels::operator[](size_t i) const
|
||||
{
|
||||
llassert(i >= 0 && i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT);
|
||||
return levels[i];
|
||||
}
|
||||
|
||||
bool LLGLTFPreviewTexture::MaterialLoadLevels::operator<(const MaterialLoadLevels& other) const
|
||||
{
|
||||
bool less = false;
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (((*this)[i] > other[i])) { return false; }
|
||||
less = less || ((*this)[i] < other[i]);
|
||||
}
|
||||
return less;
|
||||
}
|
||||
|
||||
bool LLGLTFPreviewTexture::MaterialLoadLevels::operator>(const MaterialLoadLevels& other) const
|
||||
{
|
||||
bool great = false;
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (((*this)[i] < other[i])) { return false; }
|
||||
great = great || ((*this)[i] > other[i]);
|
||||
}
|
||||
return great;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void fetch_texture_for_ui(LLPointer<LLViewerFetchedTexture>& img, const LLUUID& id)
|
||||
{
|
||||
if (id.notNull())
|
||||
{
|
||||
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
|
||||
{
|
||||
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
||||
if (obj)
|
||||
{
|
||||
LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id);
|
||||
img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
}
|
||||
}
|
||||
if (img)
|
||||
{
|
||||
img->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
img->forceToSaveRawImage(0);
|
||||
}
|
||||
};
|
||||
|
||||
// *NOTE: Does not use the same conventions as texture discard level. Lower is better.
|
||||
S32 get_texture_load_level(const LLPointer<LLViewerFetchedTexture>& texture)
|
||||
{
|
||||
if (!texture) { return FULLY_LOADED; }
|
||||
const S32 raw_level = texture->getDiscardLevel();
|
||||
if (raw_level < 0) { return NOT_LOADED; }
|
||||
return raw_level;
|
||||
}
|
||||
|
||||
LLGLTFPreviewTexture::MaterialLoadLevels get_material_load_levels(LLFetchedGLTFMaterial& material)
|
||||
{
|
||||
using MaterialTextures = LLPointer<LLViewerFetchedTexture>*[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
|
||||
|
||||
MaterialTextures textures;
|
||||
|
||||
textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = &material.mBaseColorTexture;
|
||||
textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = &material.mNormalTexture;
|
||||
textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = &material.mMetallicRoughnessTexture;
|
||||
textures[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = &material.mEmissiveTexture;
|
||||
|
||||
LLGLTFPreviewTexture::MaterialLoadLevels levels;
|
||||
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
fetch_texture_for_ui(*textures[i], material.mTextureId[i]);
|
||||
levels[i] = get_texture_load_level(*textures[i]);
|
||||
}
|
||||
|
||||
return levels;
|
||||
}
|
||||
|
||||
// Is the material loaded enough to start rendering a preview?
|
||||
bool is_material_loaded_enough_for_ui(LLFetchedGLTFMaterial& material)
|
||||
{
|
||||
if (material.isFetching())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLGLTFPreviewTexture::MaterialLoadLevels levels = get_material_load_levels(material);
|
||||
|
||||
for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i)
|
||||
{
|
||||
if (levels[i] == NOT_LOADED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
|
||||
LLGLTFPreviewTexture::LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width)
|
||||
: LLViewerDynamicTexture(width, width, 4, EOrder::ORDER_MIDDLE, FALSE)
|
||||
, mGLTFMaterial(material)
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
LLPointer<LLGLTFPreviewTexture> LLGLTFPreviewTexture::create(LLPointer<LLFetchedGLTFMaterial> material)
|
||||
{
|
||||
return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH);
|
||||
}
|
||||
|
||||
void LLGLTFPreviewTexture::preRender(BOOL clear_depth)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
|
||||
|
||||
MaterialLoadLevels current_load = get_material_load_levels(*mGLTFMaterial.get());
|
||||
if (current_load < mBestLoad)
|
||||
{
|
||||
mShouldRender = true;
|
||||
mBestLoad = current_load;
|
||||
}
|
||||
|
||||
if (!mShouldRender) { return; }
|
||||
|
||||
LLViewerDynamicTexture::preRender(clear_depth);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
struct GLTFPreviewModel
|
||||
{
|
||||
GLTFPreviewModel(LLPointer<LLDrawInfo>& info, const LLMatrix4& mat)
|
||||
: mDrawInfo(info)
|
||||
, mModelMatrix(mat)
|
||||
{
|
||||
mDrawInfo->mModelMatrix = &mModelMatrix;
|
||||
}
|
||||
LLPointer<LLDrawInfo> mDrawInfo;
|
||||
LLMatrix4 mModelMatrix; // Referenced by mDrawInfo
|
||||
};
|
||||
|
||||
// Like LLVolumeGeometryManager::registerFace but without batching or too-many-indices/vertices checking.
|
||||
std::vector<GLTFPreviewModel> create_preview_sphere(LLPointer<LLFetchedGLTFMaterial>& material, const LLMatrix4& model_matrix)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
|
||||
|
||||
const LLColor4U vertex_color(material->mBaseColor);
|
||||
|
||||
LLPrimitive prim;
|
||||
prim.init_primitive(LL_PCODE_VOLUME);
|
||||
LLVolumeParams params;
|
||||
params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
|
||||
params.setBeginAndEndS(0.f, 1.f);
|
||||
params.setBeginAndEndT(0.f, 1.f);
|
||||
params.setRatio(1, 1);
|
||||
params.setShear(0, 0);
|
||||
constexpr auto MAX_LOD = LLVolumeLODGroup::NUM_LODS - 1;
|
||||
prim.setVolume(params, MAX_LOD);
|
||||
|
||||
LLVolume* volume = prim.getVolume();
|
||||
llassert(volume);
|
||||
for (LLVolumeFace& face : volume->getVolumeFaces())
|
||||
{
|
||||
face.createTangents();
|
||||
}
|
||||
|
||||
std::vector<GLTFPreviewModel> preview_sphere;
|
||||
preview_sphere.reserve(volume->getNumFaces());
|
||||
|
||||
LLPointer<LLVertexBuffer> buf = new LLVertexBuffer(
|
||||
LLVertexBuffer::MAP_VERTEX |
|
||||
LLVertexBuffer::MAP_NORMAL |
|
||||
LLVertexBuffer::MAP_TEXCOORD0 |
|
||||
LLVertexBuffer::MAP_COLOR |
|
||||
LLVertexBuffer::MAP_TANGENT
|
||||
);
|
||||
U32 nv = 0;
|
||||
U32 ni = 0;
|
||||
for (LLVolumeFace& face : volume->getVolumeFaces())
|
||||
{
|
||||
nv += face.mNumVertices;
|
||||
ni += face.mNumIndices;
|
||||
}
|
||||
buf->allocateBuffer(nv, ni);
|
||||
|
||||
// UV hacks
|
||||
// Higher factor helps to see more details on the preview sphere
|
||||
const LLVector2 uv_factor(2.0f, 2.0f);
|
||||
// Offset places center of material in center of view
|
||||
const LLVector2 uv_offset(-0.5f, -0.5f);
|
||||
|
||||
LLStrider<U16> indices;
|
||||
LLStrider<LLVector4a> positions;
|
||||
LLStrider<LLVector4a> normals;
|
||||
LLStrider<LLVector2> texcoords;
|
||||
LLStrider<LLColor4U> colors;
|
||||
LLStrider<LLVector4a> tangents;
|
||||
buf->getIndexStrider(indices);
|
||||
buf->getVertexStrider(positions);
|
||||
buf->getNormalStrider(normals);
|
||||
buf->getTexCoord0Strider(texcoords);
|
||||
buf->getColorStrider(colors);
|
||||
buf->getTangentStrider(tangents);
|
||||
U32 index_offset = 0;
|
||||
U32 vertex_offset = 0;
|
||||
for (const LLVolumeFace& face : volume->getVolumeFaces())
|
||||
{
|
||||
for (S32 i = 0; i < face.mNumIndices; ++i)
|
||||
{
|
||||
*indices++ = face.mIndices[i] + vertex_offset;
|
||||
}
|
||||
for (S32 v = 0; v < face.mNumVertices; ++v)
|
||||
{
|
||||
*positions++ = face.mPositions[v];
|
||||
*normals++ = face.mNormals[v];
|
||||
LLVector2 uv(face.mTexCoords[v]);
|
||||
uv.scaleVec(uv_factor);
|
||||
uv += uv_offset;
|
||||
*texcoords++ = uv;
|
||||
*colors++ = vertex_color;
|
||||
*tangents++ = face.mTangents[v];
|
||||
}
|
||||
|
||||
constexpr LLViewerTexture* no_media = nullptr;
|
||||
LLPointer<LLDrawInfo> info = new LLDrawInfo(U16(vertex_offset), U16(vertex_offset + face.mNumVertices - 1), face.mNumIndices, index_offset, no_media, buf.get());
|
||||
info->mGLTFMaterial = material;
|
||||
preview_sphere.emplace_back(info, model_matrix);
|
||||
index_offset += face.mNumIndices;
|
||||
vertex_offset += face.mNumVertices;
|
||||
}
|
||||
|
||||
buf->unmapBuffer();
|
||||
|
||||
return preview_sphere;
|
||||
}
|
||||
|
||||
// Final, direct modifications to shader constants, just before render
|
||||
void fixup_shader_constants(LLGLSLShader& shader)
|
||||
{
|
||||
// Sunlight intensity of 0 no matter what
|
||||
shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
|
||||
shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, LLColor3::white.mV);
|
||||
shader.uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, 0.0f);
|
||||
|
||||
// Ignore sun shadow (if enabled)
|
||||
for (U32 i = 0; i < 6; i++)
|
||||
{
|
||||
const S32 channel = shader.getTextureChannel(LLShaderMgr::DEFERRED_SHADOW0+i);
|
||||
if (channel != -1)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(LLViewerFetchedTexture::sWhiteImagep, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set a variable to a value temporarily, and restor the variable's old value
|
||||
// when this object leaves scope.
|
||||
template<typename T>
|
||||
struct SetTemporarily
|
||||
{
|
||||
T* mRef;
|
||||
T mOldVal;
|
||||
SetTemporarily(T* var, T temp_val)
|
||||
{
|
||||
mRef = var;
|
||||
mOldVal = *mRef;
|
||||
*mRef = temp_val;
|
||||
}
|
||||
~SetTemporarily()
|
||||
{
|
||||
*mRef = mOldVal;
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
BOOL LLGLTFPreviewTexture::render()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
|
||||
|
||||
if (!mShouldRender) { return FALSE; }
|
||||
|
||||
LLGLDepthTest(GL_FALSE);
|
||||
LLGLDisable stencil(GL_STENCIL_TEST);
|
||||
LLGLDisable scissor(GL_SCISSOR_TEST);
|
||||
SetTemporarily<bool> no_glow(&LLPipeline::sRenderGlow, false);
|
||||
SetTemporarily<bool> no_ssr(&LLPipeline::RenderScreenSpaceReflections, false);
|
||||
SetTemporarily<U32> no_fxaa(&LLPipeline::RenderFSAASamples, U32(0));
|
||||
SetTemporarily<LLPipeline::RenderTargetPack*> use_auxiliary_render_target(&gPipeline.mRT, &gPipeline.mAuxillaryRT);
|
||||
|
||||
LLVector3 light_dir3(1.0f, 1.0f, 1.0f);
|
||||
light_dir3.normalize();
|
||||
const LLVector4 light_dir = LLVector4(light_dir3, 0);
|
||||
SetTemporarily<S32> sun_light_only(&LLPipeline::RenderLocalLightCount, 0);
|
||||
|
||||
gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms();
|
||||
|
||||
LLViewerCamera camera;
|
||||
|
||||
// Calculate the object distance at which the object of a given radius will
|
||||
// span the partial width of the screen given by fill_ratio.
|
||||
// Assume the primitive has a scale of 1 (this is the default).
|
||||
constexpr F32 fill_ratio = 0.8f;
|
||||
constexpr F32 object_radius = 0.5f;
|
||||
const F32 object_distance = (object_radius / fill_ratio) * tan(camera.getDefaultFOV());
|
||||
// Negative coordinate shows the textures on the sphere right-side up, when
|
||||
// combined with the UV hacks in create_preview_sphere
|
||||
const LLVector3 object_position(0.0, -object_distance, 0.0);
|
||||
LLMatrix4 object_transform;
|
||||
object_transform.translate(object_position);
|
||||
|
||||
// Set up camera and viewport
|
||||
const LLVector3 origin(0.0, 0.0, 0.0);
|
||||
camera.lookAt(origin, object_position);
|
||||
camera.setAspect(mFullHeight / mFullWidth);
|
||||
const LLRect texture_rect(0, mFullHeight, mFullWidth, 0);
|
||||
camera.setPerspective(NOT_FOR_SELECTION, texture_rect.mLeft, texture_rect.mBottom, texture_rect.getWidth(), texture_rect.getHeight(), FALSE, camera.getNear(), MAX_FAR_CLIP*2.f);
|
||||
|
||||
// Generate sphere object on-the-fly. Discard afterwards. (Vertex buffer is
|
||||
// discarded, but the sphere should be cached in LLVolumeMgr.)
|
||||
std::vector<GLTFPreviewModel> preview_sphere = create_preview_sphere(mGLTFMaterial, object_transform);
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
gPipeline.setupHWLights();
|
||||
glh::matrix4f mat = copy_matrix(gGLModelView);
|
||||
glh::vec4f transformed_light_dir(light_dir.mV);
|
||||
mat.mult_matrix_vec(transformed_light_dir);
|
||||
SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir.v));
|
||||
// Override lights to ensure the sun is always shining from a certain direction (low graphics)
|
||||
// See also force_sun_direction_high_graphics and fixup_shader_constants
|
||||
{
|
||||
LLLightState* light = gGL.getLight(0);
|
||||
light->setPosition(light_dir);
|
||||
constexpr bool sun_up = true;
|
||||
light->setSunPrimary(sun_up);
|
||||
}
|
||||
|
||||
LLRenderTarget& screen = gPipeline.mAuxillaryRT.screen;
|
||||
|
||||
#if 0
|
||||
if (mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE || mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
|
||||
{
|
||||
// *TODO: Opaque/alpha mask rendering (gDeferredPBROpaqueProgram)
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// Alpha blend rendering
|
||||
|
||||
screen.bindTarget();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
LLGLSLShader& shader = gDeferredPBRAlphaProgram;
|
||||
|
||||
gPipeline.bindDeferredShader(shader);
|
||||
fixup_shader_constants(shader);
|
||||
|
||||
for (GLTFPreviewModel& part : preview_sphere)
|
||||
{
|
||||
LLRenderPass::pushGLTFBatch(*part.mDrawInfo);
|
||||
}
|
||||
|
||||
gPipeline.unbindDeferredShader(shader);
|
||||
|
||||
screen.flush();
|
||||
}
|
||||
|
||||
gPipeline.copyScreenSpaceReflections(&screen, &gPipeline.mSceneMap);
|
||||
gPipeline.generateLuminance(&screen, &gPipeline.mLuminanceMap);
|
||||
gPipeline.generateExposure(&gPipeline.mLuminanceMap, &gPipeline.mExposureMap);
|
||||
gPipeline.gammaCorrect(&screen, &gPipeline.mPostMap);
|
||||
LLVertexBuffer::unbind();
|
||||
gPipeline.generateGlow(&gPipeline.mPostMap);
|
||||
gPipeline.combineGlow(&gPipeline.mPostMap, &screen);
|
||||
gPipeline.renderDoF(&screen, &gPipeline.mPostMap);
|
||||
gPipeline.applyFXAA(&gPipeline.mPostMap, &screen);
|
||||
|
||||
gDeferredPostNoDoFProgram.bind();
|
||||
|
||||
// From LLPipeline::renderFinalize: "Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems."
|
||||
gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &screen);
|
||||
gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, mBoundTarget, true);
|
||||
|
||||
{
|
||||
LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
|
||||
gPipeline.mScreenTriangleVB->setBuffer();
|
||||
gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
|
||||
}
|
||||
|
||||
gDeferredPostNoDoFProgram.unbind();
|
||||
|
||||
// Clean up
|
||||
gPipeline.setupHWLights();
|
||||
gPipeline.mReflectionMapManager.forceDefaultProbeAndUpdateUniforms(false);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLGLTFPreviewTexture::postRender(BOOL success)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
|
||||
|
||||
if (!mShouldRender) { return; }
|
||||
mShouldRender = false;
|
||||
|
||||
LLViewerDynamicTexture::postRender(success);
|
||||
}
|
||||
|
||||
// static
|
||||
LLPointer<LLViewerTexture> LLGLTFMaterialPreviewMgr::getPreview(LLPointer<LLFetchedGLTFMaterial> &material)
|
||||
{
|
||||
if (!material)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!is_material_loaded_enough_for_ui(*material))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return LLGLTFPreviewTexture::create(material);
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file llgltfmaterialpreviewmgr.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2023&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2023, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lldrawpool.h"
|
||||
#include "lldynamictexture.h"
|
||||
#include "llfetchedgltfmaterial.h"
|
||||
#include "llsingleton.h"
|
||||
#include "lltexture.h"
|
||||
|
||||
class LLGLTFPreviewTexture : public LLViewerDynamicTexture
|
||||
{
|
||||
protected:
|
||||
LLGLTFPreviewTexture(LLPointer<LLFetchedGLTFMaterial> material, S32 width);
|
||||
|
||||
public:
|
||||
// Width scales with size of material's textures
|
||||
static LLPointer<LLGLTFPreviewTexture> create(LLPointer<LLFetchedGLTFMaterial> material);
|
||||
|
||||
BOOL needsRender() override { return mNeedsRender; }
|
||||
void preRender(BOOL clear_depth = TRUE) override;
|
||||
BOOL render() override;
|
||||
void postRender(BOOL success) override;
|
||||
|
||||
struct MaterialLoadLevels
|
||||
{
|
||||
S32 levels[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT];
|
||||
|
||||
MaterialLoadLevels();
|
||||
|
||||
S32& operator[](size_t i);
|
||||
|
||||
const S32& operator[](size_t i) const;
|
||||
|
||||
// Less is better
|
||||
// Returns false if lhs is not strictly less or equal for all levels
|
||||
bool operator<(const MaterialLoadLevels& other) const;
|
||||
|
||||
// Less is better
|
||||
// Returns false if lhs is not strictly greater or equal for all levels
|
||||
bool operator>(const MaterialLoadLevels& other) const;
|
||||
};
|
||||
|
||||
private:
|
||||
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
|
||||
bool mNeedsRender = true;
|
||||
bool mShouldRender = true;
|
||||
MaterialLoadLevels mBestLoad;
|
||||
};
|
||||
|
||||
class LLGLTFMaterialPreviewMgr
|
||||
{
|
||||
public:
|
||||
// Returns null if the material is not loaded yet.
|
||||
// *NOTE: User should cache the texture if the same material is being previewed
|
||||
LLPointer<LLViewerTexture> getPreview(LLPointer<LLFetchedGLTFMaterial> &material);
|
||||
};
|
||||
|
||||
extern LLGLTFMaterialPreviewMgr gGLTFMaterialPreviewMgr;
|
||||
|
|
@ -27,6 +27,9 @@
|
|||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llreflectionmapmanager.h"
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "llviewercamera.h"
|
||||
#include "llspatialpartition.h"
|
||||
#include "llviewerregion.h"
|
||||
|
|
@ -1383,3 +1386,32 @@ void LLReflectionMapManager::doOcclusion()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLReflectionMapManager::forceDefaultProbeAndUpdateUniforms(bool force)
|
||||
{
|
||||
static std::bitset<LL_MAX_REFLECTION_PROBE_COUNT> mProbeWasOccluded;
|
||||
|
||||
if (force)
|
||||
{
|
||||
for (size_t i = 0; i < mProbes.size(); ++i)
|
||||
{
|
||||
auto& probe = mProbes[i];
|
||||
mProbeWasOccluded[i] = probe->mOccluded;
|
||||
if (probe != nullptr && probe != mDefaultProbe)
|
||||
{
|
||||
probe->mOccluded = true;
|
||||
}
|
||||
}
|
||||
|
||||
updateUniforms();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < mProbes.size(); ++i)
|
||||
{
|
||||
auto& probe = mProbes[i];
|
||||
llassert(probe->mOccluded == (probe != mDefaultProbe));
|
||||
probe->mOccluded = mProbeWasOccluded[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,11 @@ public:
|
|||
// perform occlusion culling on all active reflection probes
|
||||
void doOcclusion();
|
||||
|
||||
// *HACK: "cull" all reflection probes except the default one. Only call
|
||||
// this if you don't intend to call updateUniforms directly. Call again
|
||||
// with false when done.
|
||||
void forceDefaultProbeAndUpdateUniforms(bool force = true);
|
||||
|
||||
private:
|
||||
friend class LLPipeline;
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
|
||||
#include "llradiogroup.h"
|
||||
#include "llfloaterreg.h"
|
||||
#include "llgltfmaterialpreviewmgr.h"
|
||||
#include "lllocalbitmaps.h"
|
||||
#include "lllocalgltfmaterials.h"
|
||||
#include "llerror.h"
|
||||
|
|
@ -657,6 +658,7 @@ void LLFloaterTexturePicker::draw()
|
|||
if( mOwner )
|
||||
{
|
||||
mTexturep = NULL;
|
||||
LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
|
||||
mGLTFMaterial = NULL;
|
||||
if (mImageAssetID.notNull())
|
||||
{
|
||||
|
|
@ -664,10 +666,23 @@ void LLFloaterTexturePicker::draw()
|
|||
{
|
||||
mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
|
||||
llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
|
||||
{
|
||||
// Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
|
||||
if (mGLTFMaterial.isNull())
|
||||
{
|
||||
mGLTFPreview = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPointer<LLViewerFetchedTexture> texture = NULL;
|
||||
mGLTFPreview = nullptr;
|
||||
|
||||
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
|
||||
{
|
||||
|
|
@ -677,7 +692,7 @@ void LLFloaterTexturePicker::draw()
|
|||
if (obj)
|
||||
{
|
||||
LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
|
||||
texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -718,27 +733,29 @@ void LLFloaterTexturePicker::draw()
|
|||
|
||||
// If the floater is focused, don't apply its alpha to the texture (STORM-677).
|
||||
const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
LLViewerTexture* texture = nullptr;
|
||||
LLViewerTexture* preview = nullptr;
|
||||
if (mGLTFMaterial)
|
||||
{
|
||||
texture = mGLTFMaterial->getUITexture();
|
||||
preview = mGLTFPreview.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = mTexturep.get();
|
||||
preview = mTexturep.get();
|
||||
if (mTexturep)
|
||||
{
|
||||
// Pump the priority
|
||||
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
|
||||
}
|
||||
}
|
||||
|
||||
if( texture )
|
||||
if( preview )
|
||||
{
|
||||
if( texture->getComponents() == 4 )
|
||||
if( preview->getComponents() == 4 )
|
||||
{
|
||||
gl_rect_2d_checkerboard( interior, alpha );
|
||||
}
|
||||
|
||||
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), texture, UI_VERTEX_COLOR % alpha );
|
||||
|
||||
// Pump the priority
|
||||
texture->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
|
||||
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha );
|
||||
}
|
||||
else if (!mFallbackImage.isNull())
|
||||
{
|
||||
|
|
@ -2156,48 +2173,69 @@ void LLTextureCtrl::draw()
|
|||
{
|
||||
mBorder->setKeyboardFocusHighlight(hasFocus());
|
||||
|
||||
LLPointer<LLViewerTexture> preview = NULL;
|
||||
|
||||
if (!mValid)
|
||||
{
|
||||
mTexturep = NULL;
|
||||
mGLTFMaterial = NULL;
|
||||
mGLTFPreview = NULL;
|
||||
}
|
||||
else if (!mImageAssetID.isNull())
|
||||
{
|
||||
LLPointer<LLViewerFetchedTexture> texture = NULL;
|
||||
|
||||
if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
|
||||
{
|
||||
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
||||
if (obj)
|
||||
{
|
||||
LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
|
||||
texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
mTexturep = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
|
||||
mGLTFMaterial = NULL;
|
||||
mGLTFPreview = NULL;
|
||||
|
||||
preview = mTexturep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (texture.isNull())
|
||||
if (preview.isNull())
|
||||
{
|
||||
LLPointer<LLFetchedGLTFMaterial> old_material = mGLTFMaterial;
|
||||
mGLTFMaterial = NULL;
|
||||
mTexturep = NULL;
|
||||
if (mInventoryPickType == PICK_MATERIAL)
|
||||
{
|
||||
LLPointer<LLFetchedGLTFMaterial> material = gGLTFMaterialList.getMaterial(mImageAssetID);
|
||||
if (material)
|
||||
mGLTFMaterial = gGLTFMaterialList.getMaterial(mImageAssetID);
|
||||
if (mGLTFPreview.isNull() || mGLTFMaterial.isNull() || (old_material.notNull() && (*old_material.get() != *mGLTFMaterial.get())))
|
||||
{
|
||||
texture = material->getUITexture();
|
||||
// Only update the preview if needed, since gGLTFMaterialPreviewMgr does not cache the preview.
|
||||
if (mGLTFMaterial.isNull())
|
||||
{
|
||||
mGLTFPreview = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
mGLTFPreview = gGLTFMaterialPreviewMgr.getPreview(mGLTFMaterial);
|
||||
}
|
||||
}
|
||||
|
||||
preview = mGLTFPreview;
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
texture->forceToSaveRawImage(0);
|
||||
mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
|
||||
mTexturep->forceToSaveRawImage(0);
|
||||
|
||||
preview = mTexturep;
|
||||
}
|
||||
}
|
||||
|
||||
mTexturep = texture;
|
||||
}
|
||||
else//mImageAssetID == LLUUID::null
|
||||
{
|
||||
mTexturep = NULL;
|
||||
mGLTFMaterial = NULL;
|
||||
mGLTFPreview = NULL;
|
||||
}
|
||||
|
||||
// Border
|
||||
|
|
@ -2210,15 +2248,18 @@ void LLTextureCtrl::draw()
|
|||
|
||||
// If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
|
||||
const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||
if( mTexturep )
|
||||
if( preview )
|
||||
{
|
||||
if( mTexturep->getComponents() == 4 )
|
||||
if( preview->getComponents() == 4 )
|
||||
{
|
||||
gl_rect_2d_checkerboard( interior, alpha );
|
||||
}
|
||||
|
||||
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
|
||||
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
|
||||
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), preview, UI_VERTEX_COLOR % alpha);
|
||||
if (mTexturep)
|
||||
{
|
||||
mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
|
||||
}
|
||||
}
|
||||
else if (!mFallbackImage.isNull())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -250,6 +250,8 @@ private:
|
|||
commit_callback_t mOnCloseCallback;
|
||||
texture_selected_callback mOnTextureSelectedCallback;
|
||||
LLPointer<LLViewerFetchedTexture> mTexturep;
|
||||
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
|
||||
LLPointer<LLViewerTexture> mGLTFPreview;
|
||||
LLUIColor mBorderColor;
|
||||
LLUUID mImageItemID;
|
||||
LLUUID mImageAssetID;
|
||||
|
|
@ -382,6 +384,7 @@ protected:
|
|||
|
||||
LLPointer<LLViewerTexture> mTexturep;
|
||||
LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
|
||||
LLPointer<LLViewerTexture> mGLTFPreview;
|
||||
LLView* mOwner;
|
||||
|
||||
LLUUID mImageAssetID; // Currently selected texture
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ F32 LLPipeline::CameraFocusTransitionTime;
|
|||
F32 LLPipeline::CameraFNumber;
|
||||
F32 LLPipeline::CameraFocalLength;
|
||||
F32 LLPipeline::CameraFieldOfView;
|
||||
S32 LLPipeline::RenderLocalLightCount;
|
||||
F32 LLPipeline::RenderShadowNoise;
|
||||
F32 LLPipeline::RenderShadowBlurSize;
|
||||
F32 LLPipeline::RenderSSAOScale;
|
||||
|
|
@ -200,6 +201,8 @@ S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples;
|
|||
S32 LLPipeline::RenderBufferVisualization;
|
||||
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
|
||||
|
||||
const U32 LLPipeline::MAX_BAKE_WIDTH = 512;
|
||||
|
||||
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
|
||||
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
|
||||
const F32 ALPHA_BLEND_CUTOFF = 0.598f;
|
||||
|
|
@ -521,6 +524,7 @@ void LLPipeline::init()
|
|||
connectRefreshCachedSettingsSafe("CameraFNumber");
|
||||
connectRefreshCachedSettingsSafe("CameraFocalLength");
|
||||
connectRefreshCachedSettingsSafe("CameraFieldOfView");
|
||||
connectRefreshCachedSettingsSafe("RenderLocalLightCount");
|
||||
connectRefreshCachedSettingsSafe("RenderShadowNoise");
|
||||
connectRefreshCachedSettingsSafe("RenderShadowBlurSize");
|
||||
connectRefreshCachedSettingsSafe("RenderSSAOScale");
|
||||
|
|
@ -1009,6 +1013,7 @@ void LLPipeline::refreshCachedSettings()
|
|||
CameraFNumber = gSavedSettings.getF32("CameraFNumber");
|
||||
CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
|
||||
CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView");
|
||||
RenderLocalLightCount = gSavedSettings.getS32("RenderLocalLightCount");
|
||||
RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise");
|
||||
RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize");
|
||||
RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale");
|
||||
|
|
@ -1072,7 +1077,6 @@ void LLPipeline::releaseGLBuffers()
|
|||
releaseLUTBuffers();
|
||||
|
||||
mWaterDis.release();
|
||||
mBake.release();
|
||||
|
||||
mSceneMap.release();
|
||||
|
||||
|
|
@ -1151,9 +1155,6 @@ void LLPipeline::createGLBuffers()
|
|||
stop_glerror();
|
||||
assertInitialized();
|
||||
|
||||
// Use FBO for bake tex
|
||||
mBake.allocate(512, 512, GL_RGBA, true); // SL-12781 Build > Upload > Model; 3D Preview
|
||||
|
||||
stop_glerror();
|
||||
|
||||
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
|
||||
|
|
@ -5227,7 +5228,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
|
|||
return;
|
||||
}
|
||||
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
|
||||
if (local_light_count >= 1)
|
||||
{
|
||||
|
|
@ -5496,7 +5497,7 @@ void LLPipeline::setupHWLights()
|
|||
|
||||
mLightMovingMask = 0;
|
||||
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
|
||||
if (local_light_count >= 1)
|
||||
{
|
||||
|
|
@ -7930,7 +7931,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
unbindDeferredShader(gDeferredSoftenProgram);
|
||||
}
|
||||
|
||||
static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
|
||||
const S32 local_light_count = LLPipeline::RenderLocalLightCount;
|
||||
|
||||
if (local_light_count > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -694,6 +694,7 @@ public:
|
|||
RenderTargetPack mMainRT;
|
||||
|
||||
// auxillary 512x512 render target pack
|
||||
// used by reflection probes and dynamic texture bakes
|
||||
RenderTargetPack mAuxillaryRT;
|
||||
|
||||
// currently used render target pack
|
||||
|
|
@ -754,7 +755,7 @@ public:
|
|||
//water distortion texture (refraction)
|
||||
LLRenderTarget mWaterDis;
|
||||
|
||||
LLRenderTarget mBake;
|
||||
static const U32 MAX_BAKE_WIDTH;
|
||||
|
||||
//texture for making the glow
|
||||
LLRenderTarget mGlow[3];
|
||||
|
|
@ -1012,6 +1013,7 @@ public:
|
|||
static F32 CameraFNumber;
|
||||
static F32 CameraFocalLength;
|
||||
static F32 CameraFieldOfView;
|
||||
static S32 RenderLocalLightCount;
|
||||
static F32 RenderShadowNoise;
|
||||
static F32 RenderShadowBlurSize;
|
||||
static F32 RenderSSAOScale;
|
||||
|
|
|
|||
Loading…
Reference in New Issue