summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAlexander Gavriliuk <alexandrgproductengine@lindenlab.com>2024-08-07 20:56:10 +0200
committerGuru <alexandrgproductengine@lindenlab.com>2024-08-08 13:40:23 +0200
commit17f7b439d617bfdf4c865f1478ade662e86b61d2 (patch)
tree87ce6eaf3691e8ce14c98364fc81fa27e3e1eb1f /indra
parente20e387d481513e4e7eed570d224da19aa532fb8 (diff)
#1922 Make PBR scale and offset crosshair work like Texture crosshair do
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llrender.h19
-rw-r--r--indra/llrender/llvertexbuffer.cpp12
-rw-r--r--indra/llrender/llvertexbuffer.h9
-rw-r--r--indra/newview/llface.cpp116
-rw-r--r--indra/newview/llface.h4
-rw-r--r--indra/newview/pipeline.cpp159
-rw-r--r--indra/newview/pipeline.h1
7 files changed, 210 insertions, 110 deletions
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index e6b4118beb..010ab122b6 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -293,15 +293,18 @@ public:
enum eTexIndex : U8
{
- DIFFUSE_MAP = 0,
- ALTERNATE_DIFFUSE_MAP = 1,
- NORMAL_MAP = 1,
- SPECULAR_MAP = 2,
- BASECOLOR_MAP = 3,
+ // Channels for material textures
+ DIFFUSE_MAP = 0,
+ ALTERNATE_DIFFUSE_MAP = 1,
+ NORMAL_MAP = 1,
+ SPECULAR_MAP = 2,
+ // Channels for PBR textures
+ BASECOLOR_MAP = 3,
METALLIC_ROUGHNESS_MAP = 4,
- GLTF_NORMAL_MAP = 5,
- EMISSIVE_MAP = 6,
- NUM_TEXTURE_CHANNELS = 7,
+ GLTF_NORMAL_MAP = 5,
+ EMISSIVE_MAP = 6,
+ // Total number of channels
+ NUM_TEXTURE_CHANNELS = 7,
};
enum eVolumeTexIndex : U8
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 2eb7c21f77..02afcf12c6 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -794,6 +794,18 @@ void LLVertexBuffer::setLabel(const char* label) {
}
#endif
+void LLVertexBuffer::clone(LLVertexBuffer& target) const
+{
+ target.mTypeMask = mTypeMask;
+ target.mIndicesType = mIndicesType;
+ target.mIndicesStride = mIndicesStride;
+ if (target.getNumVerts() != getNumVerts() ||
+ target.getNumIndices() != getNumIndices())
+ {
+ target.allocateBuffer(getNumVerts(), getNumIndices());
+ }
+}
+
void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const
{
llassert(validateRange(start, end, count, indices_offset));
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 49500e28ce..4ada0c335b 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -163,13 +163,13 @@ public:
// set for rendering
// assumes (and will assert on) the following:
- // - this buffer has no pending unampBuffer call
+ // - this buffer has no pending unmapBuffer call
// - a shader is currently bound
// - This buffer has sufficient attributes within it to satisfy the needs of the currently bound shader
void setBuffer();
// Only call each getVertexPointer, etc, once before calling unmapBuffer()
- // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
+ // call unmapBuffer() after calls to getXXXStrider() before any calls to setBuffer()
// example:
// vb->getVertexBuffer(verts);
// vb->getNormalStrider(norms);
@@ -218,12 +218,12 @@ public:
U32 getNumIndices() const { return mNumIndices; }
U32 getTypeMask() const { return mTypeMask; }
- bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
+ bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); }
U32 getSize() const { return mSize; }
U32 getIndicesSize() const { return mIndicesSize; }
U8* getMappedData() const { return mMappedData; }
U8* getMappedIndices() const { return mMappedIndexData; }
- U32 getOffset(AttributeType type) const { return mOffsets[type]; }
+ U32 getOffset(AttributeType type) const { return mOffsets[type]; }
// these functions assume (and assert on) the current VBO being bound
// Detailed error checking can be enabled by setting gDebugGL to true
@@ -242,6 +242,7 @@ public:
void setLabel(const char* label);
#endif
+ void clone(LLVertexBuffer& target) const;
protected:
U32 mGLBuffer = 0; // GL VBO handle
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index f73c530ff9..d14a7ffddc 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -514,7 +514,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
mDrawablep->getSpatialGroup()->rebuildGeom();
mDrawablep->getSpatialGroup()->rebuildMesh();
- if(mVertexBuffer.isNull())
+ if (mVertexBuffer.isNull())
{
return;
}
@@ -567,8 +567,20 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
{
// cheaters sometimes prosper...
//
- mVertexBuffer->setBuffer();
- mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
+ LLVertexBuffer* vertex_buffer = mVertexBuffer.get();
+ // To display selection markers (white squares with the rounded cross at the center)
+ // on faces with GLTF textures we use a spectal vertex buffer with other transforms
+ if (const LLTextureEntry* te = getTextureEntry())
+ {
+ if (LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial())
+ {
+ vertex_buffer = mVertexBufferGLTF.get();
+ vertex_buffer->unmapBuffer();
+ }
+ }
+ // Draw the selection marker using the correctly chosen vertex buffer
+ vertex_buffer->setBuffer();
+ vertex_buffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
}
gGL.popMatrix();
@@ -1144,7 +1156,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
const LLMatrix3& mat_norm_in,
U16 index_offset,
bool force_rebuild,
- bool no_debug_assert)
+ bool no_debug_assert,
+ bool rebuild_for_gltf)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
llassert(verify());
@@ -1202,6 +1215,58 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
}
}
+ const LLTextureEntry* tep = mVObjp->getTE(face_index);
+ llassert(tep);
+ if (!tep)
+ return false;
+
+ LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
+ // To display selection markers (white squares with the rounded cross at the center)
+ // on faces with GLTF textures we use a special vertex buffer with other transforms
+ if (gltf_mat && !rebuild_for_gltf && tep->isSelected() && mVertexBuffer.notNull())
+ {
+ // Create a temporary vertex buffer to provide transforms for GLTF textures
+ if (mVertexBufferGLTF.isNull())
+ {
+ mVertexBufferGLTF = new LLVertexBuffer(mVertexBuffer->getTypeMask());
+ }
+
+ // Clone the existing vertex buffer into the temporary one
+ mVertexBuffer->clone(*mVertexBufferGLTF);
+
+ // Recursive call the same function with the argument rebuild_for_gltf set to true
+ // This call will make geometry in mVertexBuffer but in fact for mVertexBufferGLTF
+ mVertexBufferGLTF.swap(mVertexBufferGLTF, mVertexBuffer);
+ getGeometryVolume(volume, face_index, mat_vert_in, mat_norm_in, index_offset, force_rebuild, no_debug_assert, true);
+ mVertexBufferGLTF.swap(mVertexBufferGLTF, mVertexBuffer);
+ }
+ else if (!tep->isSelected() && mVertexBufferGLTF.notNull())
+ {
+ // Free the temporary vertex buffer when it is not needed anymore
+ mVertexBufferGLTF = nullptr;
+ }
+
+ LLGLTFMaterial::TextureInfo gltf_info_index = (LLGLTFMaterial::TextureInfo)0;
+ if (gltf_mat && rebuild_for_gltf)
+ {
+ switch (LLPipeline::sRenderHighlightTextureChannel)
+ {
+ case LLRender::BASECOLOR_MAP:
+ gltf_info_index = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR;
+ break;
+ case LLRender::METALLIC_ROUGHNESS_MAP:
+ gltf_info_index = LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS;
+ break;
+ case LLRender::GLTF_NORMAL_MAP:
+ gltf_info_index = LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL;
+ break;
+ case LLRender::EMISSIVE_MAP:
+ gltf_info_index = LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE;
+ break;
+ default:; // just to make clang happy
+ }
+ }
+
LLStrider<LLVector3> vert;
LLStrider<LLVector2> tex_coords0;
LLStrider<LLVector2> tex_coords1;
@@ -1218,7 +1283,7 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
LLVector3 scale;
if (global_volume)
{
- scale.setVec(1,1,1);
+ scale.setVec(1, 1, 1);
}
else
{
@@ -1233,7 +1298,6 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
- const LLTextureEntry *tep = mVObjp->getTE(face_index);
const U8 bump_code = tep ? tep->getBumpmap() : 0;
bool is_static = mDrawablep->isStatic();
@@ -1323,7 +1387,6 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
LLMaterial* mat = tep->getMaterialParams().get();
- LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
@@ -1334,13 +1397,27 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
S32 xforms = XFORM_NONE;
// For GLTF, transforms will be applied later
- if (rebuild_tcoord && tep && !gltf_mat)
+ if (rebuild_tcoord && tep && (!gltf_mat || rebuild_for_gltf))
{
- r = tep->getRotation();
- os = tep->mOffsetS;
- ot = tep->mOffsetT;
- ms = tep->mScaleS;
- mt = tep->mScaleT;
+ if (gltf_mat && rebuild_for_gltf)
+ {
+ // Apply special transformations for mVertexBufferGLTF
+ // They are used only to display a face selection marker
+ // (white square with a rounded cross at the center)
+ const auto& tt = gltf_mat->mTextureTransform[gltf_info_index];
+ r = -tt.mRotation * 2;
+ ms = tt.mScale[VX];
+ mt = tt.mScale[VY];
+ os += tt.mOffset[VX] + (ms - 1) / 2;
+ ot -= tt.mOffset[VY] + (mt - 1) / 2;
+ }
+ else
+ {
+ r = tep->getRotation();
+ tep->getOffset(&os, &ot);
+ tep->getScale(&ms, &mt);
+ }
+
cos_ang = cos(r);
sin_ang = sin(r);
@@ -1481,12 +1558,9 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
break;
}
- F32 s_scale = 1.f;
- F32 t_scale = 1.f;
- if( tep )
- {
- tep->getScale( &s_scale, &t_scale );
- }
+ F32 s_scale = tep->getScaleS();
+ F32 t_scale = tep->getScaleT();
+
// Use the nudged south when coming from above sun angle, such
// that emboss mapping always shows up on the upward faces of cubes when
// it's noon (since a lot of builders build with the sun forced to noon).
@@ -1508,8 +1582,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
bool tex_anim = false;
- LLVOVolume* vobj = (LLVOVolume*) (LLViewerObject*) mVObjp;
- tex_mode = vobj->mTexAnimMode;
+ LLVOVolume* vobj = (LLVOVolume*)mVObjp.get();
+ tex_mode = vobj->mTexAnimMode;
if (vobj->mTextureAnimp)
{ //texture animation is in play, override specular and normal map tex coords with diffuse texcoords
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 917f3aa0b2..7cf256f731 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -161,7 +161,8 @@ public:
const LLMatrix3& mat_normal,
U16 index_offset,
bool force_rebuild = false,
- bool no_debug_assert = false);
+ bool no_debug_assert = false,
+ bool rebuild_for_gltf = false);
// For avatar
U16 getGeometryAvatar(
@@ -266,6 +267,7 @@ public:
private:
LLPointer<LLVertexBuffer> mVertexBuffer;
+ LLPointer<LLVertexBuffer> mVertexBufferGLTF;
U32 mState;
LLFacePool* mDrawPoolp;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2a461ca84b..1b2cffa6c9 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3580,9 +3580,12 @@ void LLPipeline::postSort(LLCamera &camera)
{
mSelectedFaces.clear();
+ bool tex_index_changed = false;
if (!gNonInteractive)
{
- LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+ LLRender::eTexIndex tex_index = sRenderHighlightTextureChannel;
+ setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+ tex_index_changed = sRenderHighlightTextureChannel != tex_index;
}
// Draw face highlights for selected faces.
@@ -3604,6 +3607,24 @@ void LLPipeline::postSort(LLCamera &camera)
}
} func;
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
+
+ if (tex_index_changed)
+ {
+ // Rebuild geometry for all selected faces with PBR textures
+ for (const LLFace* face : gPipeline.mSelectedFaces)
+ {
+ if (const LLViewerObject* vobj = face->getViewerObject())
+ {
+ if (const LLTextureEntry* tep = vobj->getTE(face->getTEOffset()))
+ {
+ if (tep->getGLTFRenderMaterial())
+ {
+ gPipeline.markRebuild(face->getDrawable(), LLDrawable::REBUILD_VOLUME);
+ }
+ }
+ }
+ }
+ }
}
}
@@ -3656,28 +3677,31 @@ void render_hud_elements()
gUIProgram.unbind();
}
-void LLPipeline::renderHighlights()
+static inline void bindHighlightProgram(LLGLSLShader& program)
{
- assertInitialized();
-
- // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)
- // Render highlighted faces.
- LLGLSPipelineAlpha gls_pipeline_alpha;
- LLColor4 color(1.f, 1.f, 1.f, 0.5f);
- disableLights();
-
if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
- gHighlightProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
+ program.bind();
+ gGL.diffuseColor4f(1, 1, 1, 0.5f);
}
+}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
- {
- mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
- }
+static inline void unbindHighlightProgram(LLGLSLShader& program)
+{
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
+ {
+ program.unbind();
+ }
+}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
+void LLPipeline::renderSelectedFaces(const LLColor4& color)
+{
+ if (!mFaceSelectImagep)
+ {
+ mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
+ }
+
+ if (mFaceSelectImagep)
{
// Make sure the selection image gets downloaded and decoded
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
@@ -3693,81 +3717,61 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
}
+}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
- {
- // Paint 'em red!
- color.setVec(1.f, 0.f, 0.f, 0.5f);
-
- for (auto facep : mHighlightFaces)
- {
- facep->renderSelected(LLViewerTexture::sNullImagep, color);
- }
- }
+void LLPipeline::renderHighlights()
+{
+ assertInitialized();
- // Contains a list of the faces of objects that are physical or
- // have touch-handlers.
- mHighlightFaces.clear();
+ // Draw 3D UI elements here (before we clear the Z buffer in POOL_HUD)
+ // Render highlighted faces.
+ LLGLSPipelineAlpha gls_pipeline_alpha;
+ disableLights();
- if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
{
- gHighlightProgram.unbind();
- }
-
+ bindHighlightProgram(gHighlightProgram);
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
- {
- color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP ||
+ sRenderHighlightTextureChannel == LLRender::BASECOLOR_MAP ||
+ sRenderHighlightTextureChannel == LLRender::METALLIC_ROUGHNESS_MAP ||
+ sRenderHighlightTextureChannel == LLRender::GLTF_NORMAL_MAP ||
+ sRenderHighlightTextureChannel == LLRender::EMISSIVE_MAP ||
+ sRenderHighlightTextureChannel == LLRender::NUM_TEXTURE_CHANNELS)
{
- gHighlightNormalProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
+ static const LLColor4 highlight_selected_color(1.f, 1.f, 1.f, 0.5f);
+ renderSelectedFaces(highlight_selected_color);
}
- mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
-
- for (auto facep : mSelectedFaces)
+ // Paint 'em red!
+ static const LLColor4 highlight_face_color(1.f, 0.f, 0.f, 0.5f);
+ for (auto facep : mHighlightFaces)
{
- if (!facep || facep->getDrawable()->isDead())
- {
- LL_ERRS() << "Bad face on selection" << LL_ENDL;
- return;
- }
-
- facep->renderSelected(mFaceSelectImagep, color);
+ facep->renderSelected(LLViewerTexture::sNullImagep, highlight_face_color);
}
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightNormalProgram.unbind();
- }
+ unbindHighlightProgram(gHighlightProgram);
}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
- {
- color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
- {
- gHighlightSpecularProgram.bind();
- gGL.diffuseColor4f(1,1,1,0.5f);
- }
-
- mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+ // Contains a list of the faces of objects that are physical or
+ // have touch-handlers.
+ mHighlightFaces.clear();
- for (auto facep : mSelectedFaces)
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
+ {
+ if (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)
{
- if (!facep || facep->getDrawable()->isDead())
- {
- LL_ERRS() << "Bad face on selection" << LL_ENDL;
- return;
- }
-
- facep->renderSelected(mFaceSelectImagep, color);
+ static const LLColor4 highlight_normal_color(1.0f, 0.5f, 0.5f, 0.5f);
+ bindHighlightProgram(gHighlightNormalProgram);
+ renderSelectedFaces(highlight_normal_color);
+ unbindHighlightProgram(gHighlightNormalProgram);
}
-
- if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ else if (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)
{
- gHighlightSpecularProgram.unbind();
+ static const LLColor4 highlight_specular_color(0.0f, 0.3f, 1.0f, 0.8f);
+ bindHighlightProgram(gHighlightSpecularProgram);
+ renderSelectedFaces(highlight_specular_color);
+ unbindHighlightProgram(gHighlightSpecularProgram);
}
}
}
@@ -6256,7 +6260,10 @@ bool LLPipeline::getRenderHighlights()
// static
void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
{
- sRenderHighlightTextureChannel = channel;
+ if (channel != sRenderHighlightTextureChannel)
+ {
+ sRenderHighlightTextureChannel = channel;
+ }
}
LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 6c79d20149..4164474238 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -342,6 +342,7 @@ public:
void renderHighlight(const LLViewerObject* obj, F32 fade);
void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp);
+ void renderSelectedFaces(const LLColor4& color);
void renderHighlights();
void renderDebug();
void renderPhysicsDisplay();