Tech ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL - Replace GLIndexedVertexArray with GLModel:

TriangleSelectorGUI::m_iva_enforcers

TriangleSelectorGUI::m_iva_blockers

TriangleSelectorGUI::m_iva_seed_fills

TriangleSelectorGUI::m_varrays

GLGizmoPainterBase::s_sphere
This commit is contained in:
enricoturri1966 2022-02-09 13:13:10 +01:00
parent 4d2d77e99c
commit 8916a00821
4 changed files with 191 additions and 12 deletions

View File

@ -730,8 +730,8 @@ void GLModel::render() const
const Geometry& data = m_render_data.geometry; const Geometry& data = m_render_data.geometry;
GLenum mode = get_primitive_mode(data.format); const GLenum mode = get_primitive_mode(data.format);
GLenum index_type = get_index_type(data.format); const GLenum index_type = get_index_type(data.format);
const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format); const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format);
const bool position = Geometry::has_position(data.format); const bool position = Geometry::has_position(data.format);

View File

@ -106,6 +106,8 @@ namespace GUI {
unsigned int extract_uint_index(size_t id) const; unsigned int extract_uint_index(size_t id) const;
unsigned short extract_ushort_index(size_t id) const; unsigned short extract_ushort_index(size_t id) const;
bool is_empty() const { return vertices.empty() || indices.empty(); }
size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); } size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); }
size_t indices_count() const { return indices.size() / index_stride_bytes(format); } size_t indices_count() const { return indices.size() / index_stride_bytes(format); }

View File

@ -18,7 +18,11 @@
namespace Slic3r::GUI { namespace Slic3r::GUI {
std::shared_ptr<GLIndexedVertexArray> GLGizmoPainterBase::s_sphere = nullptr; #if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
std::shared_ptr<GLModel> GLGizmoPainterBase::s_sphere = nullptr;
#else
std::shared_ptr<GLIndexedVertexArray> GLGizmoPainterBase::s_sphere = nullptr;
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id) GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id) : GLGizmoBase(parent, icon_filename, sprite_id)
@ -27,8 +31,13 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic
GLGizmoPainterBase::~GLGizmoPainterBase() GLGizmoPainterBase::~GLGizmoPainterBase()
{ {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
if (s_sphere != nullptr)
s_sphere.reset();
#else
if (s_sphere != nullptr && s_sphere->has_VBOs()) if (s_sphere != nullptr && s_sphere->has_VBOs())
s_sphere->release_geometry(); s_sphere->release_geometry();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
} }
void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection) void GLGizmoPainterBase::set_painter_gizmo_data(const Selection& selection)
@ -220,11 +229,20 @@ void GLGizmoPainterBase::render_cursor_circle()
void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
{ {
if (s_sphere == nullptr) { if (s_sphere == nullptr) {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
s_sphere = std::make_shared<GLModel>();
s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0));
#else
s_sphere = std::make_shared<GLIndexedVertexArray>(); s_sphere = std::make_shared<GLIndexedVertexArray>();
s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0)); s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0));
s_sphere->finalize_geometry(true); s_sphere->finalize_geometry(true);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
} }
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader == nullptr)
return;
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse(); const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse();
const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed(); const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed();
@ -243,11 +261,22 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
render_color = this->get_cursor_sphere_left_button_color(); render_color = this->get_cursor_sphere_left_button_color();
else if (m_button_down == Button::Right) else if (m_button_down == Button::Right)
render_color = this->get_cursor_sphere_right_button_color(); render_color = this->get_cursor_sphere_right_button_color();
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
shader->start_using();
assert(s_sphere != nullptr);
s_sphere->set_color(render_color);
#else
glsafe(::glColor4fv(render_color.data())); glsafe(::glColor4fv(render_color.data()));
assert(s_sphere != nullptr); assert(s_sphere != nullptr);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
s_sphere->render(); s_sphere->render();
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
shader->stop_using();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
if (is_left_handed) if (is_left_handed)
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
@ -763,13 +792,28 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
shader->set_uniform("offset_depth_buffer", true); shader->set_uniform("offset_depth_buffer", true);
for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color), for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color),
std::make_pair(&m_iva_blockers, blockers_color)}) { std::make_pair(&m_iva_blockers, blockers_color)}) {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
iva.first->set_color(iva.second);
iva.first->render();
#else
if (iva.first->has_VBOs()) { if (iva.first->has_VBOs()) {
shader->set_uniform("uniform_color", iva.second); shader->set_uniform("uniform_color", iva.second);
iva.first->render(); iva.first->render();
} }
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
} }
for (auto &iva : m_iva_seed_fills) #if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (auto& iva : m_iva_seed_fills) {
size_t color_idx = &iva - &m_iva_seed_fills.front();
const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color :
color_idx == 2 ? blockers_color :
GLVolume::NEUTRAL_COLOR);
iva.set_color(color);
iva.render();
}
#else
for (auto& iva : m_iva_seed_fills)
if (iva.has_VBOs()) { if (iva.has_VBOs()) {
size_t color_idx = &iva - &m_iva_seed_fills.front(); size_t color_idx = &iva - &m_iva_seed_fills.front();
const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color : const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color :
@ -778,6 +822,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
shader->set_uniform("uniform_color", color); shader->set_uniform("uniform_color", color);
iva.render(); iva.render();
} }
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
if (m_paint_contour.has_VBO()) { if (m_paint_contour.has_VBO()) {
ScopeGuard guard_gouraud([shader]() { shader->start_using(); }); ScopeGuard guard_gouraud([shader]() { shader->start_using(); });
@ -798,7 +843,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
render_debug(imgui); render_debug(imgui);
else else
assert(false); // If you want debug output, pass ptr to ImGuiWrapper. assert(false); // If you want debug output, pass ptr to ImGuiWrapper.
#endif #endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
} }
void TriangleSelectorGUI::update_render_data() void TriangleSelectorGUI::update_render_data()
@ -807,20 +852,44 @@ void TriangleSelectorGUI::update_render_data()
int blc_cnt = 0; int blc_cnt = 0;
std::vector<int> seed_fill_cnt(m_iva_seed_fills.size(), 0); std::vector<int> seed_fill_cnt(m_iva_seed_fills.size(), 0);
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) {
iva->reset();
}
for (auto& iva : m_iva_seed_fills) {
iva.reset();
}
GLModel::Geometry iva_enforcers_data;
iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
GLModel::Geometry iva_blockers_data;
iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
std::array<GLModel::Geometry, 3> iva_seed_fills_data;
for (auto& data : iva_seed_fills_data)
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->release_geometry(); iva->release_geometry();
for (auto &iva : m_iva_seed_fills) for (auto &iva : m_iva_seed_fills)
iva.release_geometry(); iva.release_geometry();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (const Triangle &tr : m_triangles) { for (const Triangle &tr : m_triangles) {
if (!tr.valid() || tr.is_split() || (tr.get_state() == EnforcerBlockerType::NONE && !tr.is_selected_by_seed_fill())) if (!tr.valid() || tr.is_split() || (tr.get_state() == EnforcerBlockerType::NONE && !tr.is_selected_by_seed_fill()))
continue; continue;
int tr_state = int(tr.get_state()); int tr_state = int(tr.get_state());
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLModel::Geometry &iva = tr.is_selected_by_seed_fill() ? iva_seed_fills_data[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? iva_enforcers_data :
iva_blockers_data;
#else
GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] : GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers :
m_iva_blockers; m_iva_blockers;
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] : int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt :
blc_cnt; blc_cnt;
@ -830,18 +899,36 @@ void TriangleSelectorGUI::update_render_data()
//FIXME the normal may likely be pulled from m_triangle_selectors, but it may not be worth the effort //FIXME the normal may likely be pulled from m_triangle_selectors, but it may not be worth the effort
// or the current implementation may be more cache friendly. // or the current implementation may be more cache friendly.
const Vec3f n = (v1 - v0).cross(v2 - v1).normalized(); const Vec3f n = (v1 - v0).cross(v2 - v1).normalized();
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
iva.add_vertex(v0, n);
iva.add_vertex(v1, n);
iva.add_vertex(v2, n);
iva.add_uint_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
#else
iva.push_geometry(v0, n); iva.push_geometry(v0, n);
iva.push_geometry(v1, n); iva.push_geometry(v1, n);
iva.push_geometry(v2, n); iva.push_geometry(v2, n);
iva.push_triangle(cnt, cnt + 1, cnt + 2); iva.push_triangle(cnt, cnt + 1, cnt + 2);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
cnt += 3; cnt += 3;
} }
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
if (!iva_enforcers_data.is_empty())
m_iva_enforcers.init_from(std::move(iva_enforcers_data));
if (!iva_blockers_data.is_empty())
m_iva_blockers.init_from(std::move(iva_blockers_data));
for (size_t i = 0; i < m_iva_seed_fills.size(); ++i) {
if (!iva_seed_fills_data[i].is_empty())
m_iva_seed_fills[i].init_from(std::move(iva_seed_fills_data[i]));
}
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->finalize_geometry(true); iva->finalize_geometry(true);
for (auto &iva : m_iva_seed_fills) for (auto &iva : m_iva_seed_fills)
iva.finalize_geometry(true); iva.finalize_geometry(true);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
m_paint_contour.release_geometry(); m_paint_contour.release_geometry();
std::vector<Vec2i> contour_edges = this->get_seed_fill_contour(); std::vector<Vec2i> contour_edges = this->get_seed_fill_contour();
@ -956,45 +1043,111 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
INVALID INVALID
}; };
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (auto& va : m_varrays)
va.reset();
#else
for (auto& va : m_varrays) for (auto& va : m_varrays)
va.release_geometry(); va.release_geometry();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
std::array<int, 3> cnts; std::array<int, 3> cnts;
::glScalef(1.01f, 1.01f, 1.01f); ::glScalef(1.01f, 1.01f, 1.01f);
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
std::array<GLModel::Geometry, 3> varrays_data;
for (auto& data : varrays_data)
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (int tr_id=0; tr_id<int(m_triangles.size()); ++tr_id) { for (int tr_id=0; tr_id<int(m_triangles.size()); ++tr_id) {
const Triangle& tr = m_triangles[tr_id]; const Triangle& tr = m_triangles[tr_id];
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLModel::Geometry* va = nullptr;
#else
GLIndexedVertexArray* va = nullptr; GLIndexedVertexArray* va = nullptr;
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
int* cnt = nullptr; int* cnt = nullptr;
if (tr_id < m_orig_size_indices) { if (tr_id < m_orig_size_indices) {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
va = &varrays_data[ORIGINAL];
#else
va = &m_varrays[ORIGINAL]; va = &m_varrays[ORIGINAL];
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
cnt = &cnts[ORIGINAL]; cnt = &cnts[ORIGINAL];
} }
else if (tr.valid()) { else if (tr.valid()) {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
va = &varrays_data[SPLIT];
#else
va = &m_varrays[SPLIT]; va = &m_varrays[SPLIT];
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
cnt = &cnts[SPLIT]; cnt = &cnts[SPLIT];
} }
else { else {
if (! m_show_invalid) if (! m_show_invalid)
continue; continue;
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
va = &varrays_data[INVALID];
#else
va = &m_varrays[INVALID]; va = &m_varrays[INVALID];
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
cnt = &cnts[INVALID]; cnt = &cnts[INVALID];
} }
for (int i=0; i<3; ++i) #if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (int i = 0; i < 3; ++i) {
va->add_vertex(m_vertices[tr.verts_idxs[i]].v, Vec3f(0.0f, 0.0f, 1.0f));
}
va->add_uint_triangle((unsigned int)*cnt, (unsigned int)*cnt + 1, (unsigned int)*cnt + 2);
#else
for (int i = 0; i < 3; ++i)
va->push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), va->push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]),
double(m_vertices[tr.verts_idxs[i]].v[1]), double(m_vertices[tr.verts_idxs[i]].v[1]),
double(m_vertices[tr.verts_idxs[i]].v[2]), double(m_vertices[tr.verts_idxs[i]].v[2]),
0., 0., 1.); 0., 0., 1.);
va->push_triangle(*cnt, va->push_triangle(*cnt,
*cnt+1, *cnt + 1,
*cnt+2); *cnt + 2);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
*cnt += 3; *cnt += 3;
} }
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
for (int i = 0; i < 3; ++i) {
if (!varrays_data[i].is_empty())
m_varrays[i].init_from(std::move(varrays_data[i]));
}
#else
for (auto* iva : { &m_iva_enforcers, &m_iva_blockers })
iva->finalize_geometry(true);
for (auto& iva : m_iva_seed_fills)
iva.finalize_geometry(true);
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
GLShaderProgram* shader = wxGetApp().get_shader("flat");
if (shader != nullptr) {
shader->start_using();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); ::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
for (vtype i : {ORIGINAL, SPLIT, INVALID}) { for (vtype i : {ORIGINAL, SPLIT, INVALID}) {
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLModel& va = m_varrays[i];
switch (i) {
case ORIGINAL: va.set_color({ 0.0f, 0.0f, 1.0f, 1.0f }); break;
case SPLIT: va.set_color({ 1.0f, 0.0f, 0.0f, 1.0f }); break;
case INVALID: va.set_color({ 1.0f, 1.0f, 0.0f, 1.0f }); break;
}
va.render();
#else
GLIndexedVertexArray& va = m_varrays[i]; GLIndexedVertexArray& va = m_varrays[i];
va.finalize_geometry(true); va.finalize_geometry(true);
if (va.has_VBOs()) { if (va.has_VBOs()) {
@ -1005,11 +1158,18 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
} }
va.render(); va.render();
} }
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
} }
::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); ::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
shader->stop_using();
}
if (curr_shader != nullptr)
curr_shader->start_using();
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
} }
#endif #endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
} // namespace Slic3r::GUI } // namespace Slic3r::GUI

View File

@ -3,7 +3,11 @@
#include "GLGizmoBase.hpp" #include "GLGizmoBase.hpp"
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
#include "slic3r/GUI/GLModel.hpp"
#else
#include "slic3r/GUI/3DScene.hpp" #include "slic3r/GUI/3DScene.hpp"
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
#include "libslic3r/ObjectID.hpp" #include "libslic3r/ObjectID.hpp"
#include "libslic3r/TriangleSelector.hpp" #include "libslic3r/TriangleSelector.hpp"
@ -81,7 +85,7 @@ public:
void render_debug(ImGuiWrapper* imgui); void render_debug(ImGuiWrapper* imgui);
bool m_show_triangles{false}; bool m_show_triangles{false};
bool m_show_invalid{false}; bool m_show_invalid{false};
#endif #endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
protected: protected:
bool m_update_render_data = false; bool m_update_render_data = false;
@ -91,10 +95,19 @@ protected:
private: private:
void update_render_data(); void update_render_data();
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
GLModel m_iva_enforcers;
GLModel m_iva_blockers;
std::array<GLModel, 3> m_iva_seed_fills;
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
std::array<GLModel, 3> m_varrays;
#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
#else
GLIndexedVertexArray m_iva_enforcers; GLIndexedVertexArray m_iva_enforcers;
GLIndexedVertexArray m_iva_blockers; GLIndexedVertexArray m_iva_blockers;
std::array<GLIndexedVertexArray, 3> m_iva_seed_fills; std::array<GLIndexedVertexArray, 3> m_iva_seed_fills;
std::array<GLIndexedVertexArray, 3> m_varrays; std::array<GLIndexedVertexArray, 3> m_varrays;
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
protected: protected:
GLPaintContour m_paint_contour; GLPaintContour m_paint_contour;
@ -209,7 +222,11 @@ private:
const Camera& camera, const Camera& camera,
const std::vector<Transform3d>& trafo_matrices) const; const std::vector<Transform3d>& trafo_matrices) const;
#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
static std::shared_ptr<GLModel> s_sphere;
#else
static std::shared_ptr<GLIndexedVertexArray> s_sphere; static std::shared_ptr<GLIndexedVertexArray> s_sphere;
#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
bool m_internal_stack_active = false; bool m_internal_stack_active = false;
bool m_schedule_update = false; bool m_schedule_update = false;