summaryrefslogtreecommitdiff
path: root/indra/newview/llspatialpartition.cpp
diff options
context:
space:
mode:
authorRunitaiLinden <davep@lindenlab.com>2024-02-07 11:20:06 -0600
committerRunitaiLinden <davep@lindenlab.com>2024-02-07 11:20:06 -0600
commit78cc23f89ce01eff6531d4130bdb8016296043a6 (patch)
treebc89602fc63bb40b15f76ce91b7cb6d33d4511d8 /indra/newview/llspatialpartition.cpp
parentb0c7dc653dc730f1f95aa95fc6df876dfe7b04a0 (diff)
parent7a5b0f5acf0b8aee3e73af0eb15d8c6930b98243 (diff)
Merge branch 'release/materials_featurette' into materials_featurette/mirrors
Diffstat (limited to 'indra/newview/llspatialpartition.cpp')
-rw-r--r--indra/newview/llspatialpartition.cpp171
1 files changed, 123 insertions, 48 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 931880a475..40e8e526d1 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -47,6 +47,7 @@
#include "pipeline.h"
#include "llmeshrepository.h"
#include "llrender.h"
+#include "lldrawpool.h"
#include "lloctree.h"
#include "llphysicsshapebuilderutil.h"
#include "llvoavatar.h"
@@ -2000,7 +2001,11 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
drawBoxOutline(pos,size);
}
}
-
+// *TODO: LLDrawables which are not part of LLVOVolumes fall into a different
+// code path which uses a shader - it was tested to be faster than mapping a
+// vertex buffer in the terrain case. Consider using it for LLVOVolumes as well
+// to simplify and speed up this debug code. Alternatively, a compute shader is
+// likely faster. -Cosmic,2023-09-28
void renderNormals(LLDrawable *drawablep)
{
if (!drawablep->isVisible())
@@ -2008,11 +2013,13 @@ void renderNormals(LLDrawable *drawablep)
LLVertexBuffer::unbind();
+ LLViewerObject* obj = drawablep->getVObj();
LLVOVolume *vol = drawablep->getVOVolume();
- if (vol)
+ if (obj)
{
- LLVolume *volume = vol->getVolume();
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest gl_depth(GL_TRUE, GL_FALSE);
// Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
//
@@ -2021,68 +2028,136 @@ void renderNormals(LLDrawable *drawablep)
// transform. We get that effect here by pre-applying the inverse scale (twice, because
// one forward scale will be re-applied via the MVP in the vertex shader)
- LLVector3 scale_v3 = vol->getScale();
- float scale_len = scale_v3.length();
- LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
- obj_scale.normalize3();
+ LLVector4a inv_scale;
+ float scale_len;
+ if (vol)
+ {
+ LLVector3 scale_v3 = vol->getScale();
+ LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
+ obj_scale.normalize3();
- // Normals &tangent line segments get scaled along with the object. Divide by scale length
- // to keep the as-viewed lengths (relatively) constant with the debug setting length
- float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+ // Create inverse-scale vector for normals
+ inv_scale.set(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ], 0.0);
+ inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
- // Create inverse-scale vector for normals
- LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
- inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
- inv_scale.normalize3fast();
+ inv_scale.normalize3fast();
+ scale_len = scale_v3.length();
+ }
+ else
+ {
+ inv_scale.set(1.0, 1.0, 1.0, 0.0);
+ scale_len = 1.0;
+ }
gGL.pushMatrix();
- gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+ if (vol)
+ {
+ gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+ }
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ // Normals &tangent line segments get scaled along with the object. Divide by scale length
+ // to keep the as-viewed lengths (relatively) constant with the debug setting length
+ float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+
+ std::vector<LLVolumeFace>* faces = nullptr;
+ std::vector<LLFace*>* drawable_faces = nullptr;
+ if (vol)
+ {
+ LLVolume* volume = vol->getVolume();
+ faces = &volume->getVolumeFaces();
+ }
+ else
{
- const LLVolumeFace &face = volume->getVolumeFace(i);
+ drawable_faces = &drawablep->getFaces();
+ }
- gGL.flush();
- gGL.diffuseColor4f(1, 1, 0, 1);
- gGL.begin(LLRender::LINES);
- for (S32 j = 0; j < face.mNumVertices; ++j)
- {
- LLVector4a n, p;
+ if (faces)
+ {
+ for (auto it = faces->begin(); it != faces->end(); ++it)
+ {
+ const LLVolumeFace& face = *it;
+
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a n, p;
- n.setMul(face.mNormals[j], 1.0);
- n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
- n.normalize3fast();
- n.mul(draw_length);
- p.setAdd(face.mPositions[j], n);
+ n.setMul(face.mNormals[j], 1.0);
+ n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
+ n.normalize3fast();
+ n.mul(draw_length);
+ p.setAdd(face.mPositions[j], n);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+
+ // Tangents are simple vectors and do not require reorientation via pre-scaling
+ if (face.mTangents)
+ {
+ gGL.flush();
+ gGL.diffuseColor4f(0, 1, 1, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a t, p;
- // Tangents are simple vectors and do not require reorientation via pre-scaling
- if (face.mTangents)
+ t.setMul(face.mTangents[j], 1.0f);
+ t.normalize3fast();
+ t.mul(draw_length);
+ p.setAdd(face.mPositions[j], t);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+ }
+ }
+ }
+ else if (drawable_faces)
+ {
+ // *HACK: Prepare to restore previous shader as other debug code depends on a simpler shader being present
+ llassert(LLGLSLShader::sCurBoundShaderPtr == &gDebugProgram);
+ LLGLSLShader* prev_shader = LLGLSLShader::sCurBoundShaderPtr;
+ for (auto it = drawable_faces->begin(); it != drawable_faces->end(); ++it)
{
- gGL.flush();
- gGL.diffuseColor4f(0, 1, 1, 1);
- gGL.begin(LLRender::LINES);
- for (S32 j = 0; j < face.mNumVertices; ++j)
+ LLFace* facep = *it;
+ LLFace& face = **it;
+ LLVertexBuffer* buf = face.getVertexBuffer();
+ if (!buf) { continue; }
+ U32 mask_vn = LLVertexBuffer::TYPE_VERTEX | LLVertexBuffer::TYPE_NORMAL;
+ if ((buf->getTypeMask() & mask_vn) != mask_vn) { continue; }
+
+ LLGLSLShader* shader;
+ if ((buf->getTypeMask() & LLVertexBuffer::TYPE_TANGENT) != LLVertexBuffer::TYPE_TANGENT)
{
- LLVector4a t, p;
+ shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_DEFAULT];
+ }
+ else
+ {
+ shader = &gNormalDebugProgram[NORMAL_DEBUG_SHADER_WITH_TANGENTS];
+ }
+ shader->bind();
- t.setMul(face.mTangents[j], 1.0f);
- t.normalize3fast();
- t.mul(draw_length);
- p.setAdd(face.mPositions[j], t);
+ shader->uniform1f(LLShaderMgr::DEBUG_NORMAL_DRAW_LENGTH, draw_length);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
+ LLRenderPass::applyModelMatrix(&facep->getDrawable()->getRegion()->mRenderMatrix);
+
+ buf->setBuffer();
+ // *NOTE: The render type in the vertex shader is TRIANGLES, but gets converted to LINES in the geometry shader
+ // *NOTE: For terrain normal debug, this seems to also include vertices for water, which is technically not part of the terrain. Should fix that at some point.
+ buf->drawRange(LLRender::TRIANGLES, face.getGeomIndex(), face.getGeomIndex() + face.getGeomCount()-1, face.getIndicesCount(), face.getIndicesStart());
}
- }
+ if (prev_shader)
+ {
+ prev_shader->bind();
+ }
+ }
gGL.popMatrix();
}