From 275fafd0af70af8fcfacb852dd78ffb67315fd63 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Tue, 23 Dec 2025 15:19:52 -0500 Subject: [PATCH 1/3] add missing setAttribute() variants --- include/polyscope/render/engine.h | 4 ++ .../render/mock_opengl/mock_gl_engine.h | 4 ++ include/polyscope/render/opengl/gl_engine.h | 4 ++ src/render/mock_opengl/mock_gl_engine.cpp | 45 +++++++++++++++++ src/render/opengl/gl_engine.cpp | 48 +++++++++++++++++++ 5 files changed, 105 insertions(+) diff --git a/include/polyscope/render/engine.h b/include/polyscope/render/engine.h index 6f69090a..5fe4c9d4 100644 --- a/include/polyscope/render/engine.h +++ b/include/polyscope/render/engine.h @@ -381,6 +381,10 @@ class ShaderProgram { virtual void setAttribute(std::string name, const std::vector& data) = 0; virtual void setAttribute(std::string name, const std::vector& data) = 0; virtual void setAttribute(std::string name, const std::vector& data) = 0; + + virtual void setAttribute(std::string name, const std::vector>& data) = 0; + virtual void setAttribute(std::string name, const std::vector>& data) = 0; + virtual void setAttribute(std::string name, const std::vector>& data) = 0; // clang-format on diff --git a/include/polyscope/render/mock_opengl/mock_gl_engine.h b/include/polyscope/render/mock_opengl/mock_gl_engine.h index bcdb7e3e..53b27768 100644 --- a/include/polyscope/render/mock_opengl/mock_gl_engine.h +++ b/include/polyscope/render/mock_opengl/mock_gl_engine.h @@ -274,6 +274,10 @@ class GLShaderProgram : public ShaderProgram { void setAttribute(std::string name, const std::vector& data) override; void setAttribute(std::string name, const std::vector& data) override; void setAttribute(std::string name, const std::vector& data) override; + + void setAttribute(std::string name, const std::vector>& data) override; + void setAttribute(std::string name, const std::vector>& data) override; + void setAttribute(std::string name, const std::vector>& data) override; // clang-format on // Indices diff --git a/include/polyscope/render/opengl/gl_engine.h b/include/polyscope/render/opengl/gl_engine.h index ba57b9bd..c2e2c8fa 100644 --- a/include/polyscope/render/opengl/gl_engine.h +++ b/include/polyscope/render/opengl/gl_engine.h @@ -317,6 +317,10 @@ class GLShaderProgram : public ShaderProgram { void setAttribute(std::string name, const std::vector& data) override; void setAttribute(std::string name, const std::vector& data) override; void setAttribute(std::string name, const std::vector& data) override; + + void setAttribute(std::string name, const std::vector>& data) override; + void setAttribute(std::string name, const std::vector>& data) override; + void setAttribute(std::string name, const std::vector>& data) override; // clang-format on diff --git a/src/render/mock_opengl/mock_gl_engine.cpp b/src/render/mock_opengl/mock_gl_engine.cpp index 13471421..5eee0961 100644 --- a/src/render/mock_opengl/mock_gl_engine.cpp +++ b/src/render/mock_opengl/mock_gl_engine.cpp @@ -1228,6 +1228,51 @@ void GLShaderProgram::setAttribute(std::string name, const std::vector throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); } +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name) { + if (a.arrayCount != 2) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name) { + if (a.arrayCount != 3) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name) { + if (a.arrayCount != 4) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + bool GLShaderProgram::hasTexture(std::string name) { for (GLShaderTexture& t : textures) { if (t.name == name) { diff --git a/src/render/opengl/gl_engine.cpp b/src/render/opengl/gl_engine.cpp index 779294a2..da090dd2 100644 --- a/src/render/opengl/gl_engine.cpp +++ b/src/render/opengl/gl_engine.cpp @@ -1751,6 +1751,54 @@ void GLShaderProgram::setAttribute(std::string name, const std::vector throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); } +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + glBindVertexArray(vaoHandle); + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name && a.location != -1) { + if (a.arrayCount != 2) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + glBindVertexArray(vaoHandle); + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name && a.location != -1) { + if (a.arrayCount != 3) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + +void GLShaderProgram::setAttribute(std::string name, const std::vector>& data) { + glBindVertexArray(vaoHandle); + + // pass-through to the buffer + for (GLShaderAttribute& a : attributes) { + if (a.name == name && a.location != -1) { + if (a.arrayCount != 4) throw std::invalid_argument("Tried to set attribute " + name + " with wrong array count"); + ensureBufferExists(a); + a.buff->setData(data); + return; + } + } + + throw std::invalid_argument("Tried to set nonexistent attribute with name " + name); +} + bool GLShaderProgram::hasTexture(std::string name) { for (GLShaderTexture& t : textures) { if (t.name == name && t.location != -1) { From 13ea1f530dc1017d2d150bf99fc447be412fd039 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Tue, 23 Dec 2025 15:23:34 -0500 Subject: [PATCH 2/3] set attribute directly in camera view (fixes multiple-set bug) --- src/camera_view.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/camera_view.cpp b/src/camera_view.cpp index 7a3f2962..8c499df7 100644 --- a/src/camera_view.cpp +++ b/src/camera_view.cpp @@ -317,11 +317,7 @@ void CameraView::fillCameraWidgetGeometry(render::ShaderProgram* nodeProgram, re std::array{pickColor, pickColor, pickColor}); - std::shared_ptr tripleColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float, 3); - tripleColorsBuff->setData(tripleColors); - - pickFrameProgram->setAttribute("a_vertexColors", tripleColorsBuff); + pickFrameProgram->setAttribute("a_vertexColors", tripleColors); pickFrameProgram->setAttribute("a_faceColor", faceColor); if (wantsCullPosition()) { pickFrameProgram->setAttribute("a_cullPos", cullPos); From 25e7502ec5331c43b76d9ee3a5e3e2d102180340 Mon Sep 17 00:00:00 2001 From: Nicholas Sharp Date: Tue, 23 Dec 2025 15:28:18 -0500 Subject: [PATCH 3/3] use direct set attribute almost everywhere --- src/surface_mesh.cpp | 24 ++++-------------------- src/volume_mesh.cpp | 7 +------ 2 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/surface_mesh.cpp b/src/surface_mesh.cpp index fe198f81..0d7809f7 100644 --- a/src/surface_mesh.cpp +++ b/src/surface_mesh.cpp @@ -1040,27 +1040,11 @@ void SurfaceMesh::setMeshPickAttributes(render::ShaderProgram& p) { // == Store data in buffers - std::shared_ptr vertexColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float, 3); - vertexColorsBuff->setData(vertexColors); - pickProgram->setAttribute("a_vertexColors", vertexColorsBuff); - - std::shared_ptr faceColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float); - faceColorsBuff->setData(faceColor); - pickProgram->setAttribute("a_faceColor", faceColorsBuff); - + pickProgram->setAttribute("a_vertexColors", vertexColors); + pickProgram->setAttribute("a_faceColor", faceColor); if (!usingSimplePick) { - - std::shared_ptr halfedgeColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float, 3); - halfedgeColorsBuff->setData(halfedgeColors); - pickProgram->setAttribute("a_halfedgeColors", halfedgeColorsBuff); - - std::shared_ptr cornerColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float, 3); - cornerColorsBuff->setData(cornerColors); - pickProgram->setAttribute("a_cornerColors", cornerColorsBuff); + pickProgram->setAttribute("a_halfedgeColors", halfedgeColors); + pickProgram->setAttribute("a_cornerColors", cornerColors); } } diff --git a/src/volume_mesh.cpp b/src/volume_mesh.cpp index 78094bbc..e79503aa 100644 --- a/src/volume_mesh.cpp +++ b/src/volume_mesh.cpp @@ -599,12 +599,7 @@ void VolumeMesh::preparePick() { } // === Store data in buffers - - std::shared_ptr vertexColorsBuff = - render::engine->generateAttributeBuffer(RenderDataType::Vector3Float, 3); - vertexColorsBuff->setData(vertexColors); - - pickProgram->setAttribute("a_vertexColors", vertexColorsBuff); + pickProgram->setAttribute("a_vertexColors", vertexColors); pickProgram->setAttribute("a_faceColor", faceColor); }