NEW: add silhouette effect
jira: STUDIO-8928 Change-Id: Ia64a96e7e13e65d8be85fddfedcfdc4e5cff4ed5 (cherry picked from commit f090726830ea0490994b62c93c93e18ead731681)
This commit is contained in:
parent
0098b8a347
commit
fd2524a09e
|
@ -0,0 +1,6 @@
|
|||
#version 110
|
||||
uniform vec4 u_base_color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = u_base_color;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#version 110
|
||||
|
||||
uniform mat4 u_model_matrix;
|
||||
uniform mat4 u_view_projection_matrix;
|
||||
|
||||
attribute vec3 v_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_view_projection_matrix * u_model_matrix * vec4(v_position, 1.0);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#version 110
|
||||
uniform sampler2D u_sampler;
|
||||
uniform mat3 u_convolution_matrix;
|
||||
uniform vec2 u_viewport_size;
|
||||
|
||||
varying vec2 tex_coords;
|
||||
|
||||
vec4 sample(float offsetX, float offsetY)
|
||||
{
|
||||
return texture2D(u_sampler, vec2(tex_coords.x + offsetX, tex_coords.y + offsetY));
|
||||
}
|
||||
void main()
|
||||
{
|
||||
vec4 pixels[9];
|
||||
float deltaWidth = 1.0 / u_viewport_size.x;
|
||||
float deltaHeight = 1.0 / u_viewport_size.y;
|
||||
pixels[0] = sample(-deltaWidth, deltaHeight );
|
||||
pixels[1] = sample(0.0, deltaHeight );
|
||||
pixels[2] = sample(deltaWidth, deltaHeight );
|
||||
pixels[3] = sample(-deltaWidth, 0.0);
|
||||
pixels[4] = sample(0.0, 0.0);
|
||||
pixels[5] = sample(deltaWidth, 0.0);
|
||||
pixels[6] = sample(-deltaWidth, -deltaHeight);
|
||||
pixels[7] = sample(0.0, -deltaHeight);
|
||||
pixels[8] = sample(deltaWidth, -deltaHeight);
|
||||
vec4 accumulator = vec4(0.0);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
accumulator += pixels[3 * i + j] * u_convolution_matrix[i][j];
|
||||
}
|
||||
}
|
||||
gl_FragColor = accumulator;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#version 110
|
||||
|
||||
attribute vec3 v_position;
|
||||
attribute vec2 v_tex_coord;
|
||||
|
||||
varying vec2 tex_coords;
|
||||
|
||||
void main()
|
||||
{
|
||||
tex_coords = v_tex_coord;
|
||||
gl_Position = vec4(v_position, 1.0);
|
||||
}
|
|
@ -5857,11 +5857,13 @@ int CLI::run(int argc, char **argv)
|
|||
thumbnails.push_back(ThumbnailData());
|
||||
Point isize(size); // round to ints
|
||||
ThumbnailData& thumbnail_data = thumbnails.back();
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") %Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Supported:
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(thumbnail_data,
|
||||
isize.x(), isize.y(), params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
|
@ -5869,14 +5871,12 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(thumbnail_data,
|
||||
isize.x(), isize.y(), params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
||||
break;
|
||||
}
|
||||
if (!thumbnails.back().is_valid())
|
||||
|
@ -6432,11 +6432,13 @@ int CLI::run(int argc, char **argv)
|
|||
const ThumbnailsParams thumbnail_params = {{}, false, true, true, true, i};
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail, need to regenerate")%(i+1);
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Supported:
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
|
@ -6444,14 +6446,12 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
||||
break;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s thumbnail,finished rendering")%(i+1);
|
||||
|
@ -6484,11 +6484,13 @@ int CLI::run(int argc, char **argv)
|
|||
const ThumbnailsParams thumbnail_params = { {}, false, true, false, true, i };
|
||||
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%'s no_light_thumbnail_file missed, need to regenerate")%(i+1);
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Supported:
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*no_light_thumbnail,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true);
|
||||
|
@ -6496,14 +6498,12 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*no_light_thumbnail,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, false, false, true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
||||
break;
|
||||
}
|
||||
plate_data->no_light_thumbnail_file = "valid_no_light";
|
||||
|
@ -6568,11 +6568,13 @@ int CLI::run(int argc, char **argv)
|
|||
BOOST_LOG_TRIVIAL(info) << boost::format("skip rendering for top&&pick");
|
||||
}
|
||||
else {
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Supported:
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*top_thumbnail,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false);
|
||||
|
@ -6583,7 +6585,6 @@ int CLI::run(int argc, char **argv)
|
|||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*top_thumbnail,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model.objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho, true, false);
|
||||
|
@ -6593,7 +6594,6 @@ int CLI::run(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: unknown");
|
||||
break;
|
||||
}
|
||||
plate_data->top_file = "valid_top";
|
||||
|
|
|
@ -107,6 +107,7 @@ set(SLIC3R_GUI_SOURCES
|
|||
GUI/GLShader.hpp
|
||||
GUI/GLCanvas3D.hpp
|
||||
GUI/GLCanvas3D.cpp
|
||||
GUI/GLEnums.hpp
|
||||
GUI/OpenGLManager.hpp
|
||||
GUI/OpenGLManager.cpp
|
||||
GUI/Selection.hpp
|
||||
|
|
|
@ -1552,7 +1552,8 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo
|
|||
}
|
||||
|
||||
//BBS: add outline drawing logic
|
||||
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
||||
void GLVolumeCollection::render(GUI::ERenderPipelineStage render_pipeline_stage,
|
||||
GLVolumeCollection::ERenderType type,
|
||||
bool disable_cullface,
|
||||
const Transform3d & view_matrix,
|
||||
std::function<bool(const GLVolume &)> filter_func,
|
||||
|
@ -1599,77 +1600,88 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
|||
#endif // ENABLE_MODIFIERS_ALWAYS_TRANSPARENT
|
||||
|
||||
// render sinking contours of non-hovered volumes
|
||||
if (m_show_sinking_contours)
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
|
||||
shader->stop_using();
|
||||
volume.first->render_sinking_contours();
|
||||
shader->start_using();
|
||||
}
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
if (m_show_sinking_contours)
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||
volume.first->hover == GLVolume::HS_None && !volume.first->force_sinking_contours) {
|
||||
shader->stop_using();
|
||||
volume.first->render_sinking_contours();
|
||||
shader->start_using();
|
||||
}
|
||||
}
|
||||
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
|
||||
|
||||
shader->set_uniform("is_text_shape", volume.first->is_text_shape);
|
||||
shader->set_uniform("uniform_color", volume.first->render_color);
|
||||
shader->set_uniform("z_range", m_z_range, 2);
|
||||
shader->set_uniform("clipping_plane", m_clipping_plane, 4);
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format("set uniform_color to {%1%, %2%, %3%, %4%}, with_outline=%5%, selected %6%")
|
||||
// %volume.first->render_color[0]%volume.first->render_color[1]%volume.first->render_color[2]%volume.first->render_color[3]
|
||||
// %with_outline%volume.first->selected;
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
shader->set_uniform("is_text_shape", volume.first->is_text_shape);
|
||||
shader->set_uniform("uniform_color", volume.first->render_color);
|
||||
shader->set_uniform("z_range", m_z_range, 2);
|
||||
shader->set_uniform("clipping_plane", m_clipping_plane, 4);
|
||||
//BOOST_LOG_TRIVIAL(info) << boost::format("set uniform_color to {%1%, %2%, %3%, %4%}, with_outline=%5%, selected %6%")
|
||||
// %volume.first->render_color[0]%volume.first->render_color[1]%volume.first->render_color[2]%volume.first->render_color[3]
|
||||
// %with_outline%volume.first->selected;
|
||||
|
||||
//BBS set print_volume to render volume
|
||||
//shader->set_uniform("print_volume.type", static_cast<int>(m_render_volume.type));
|
||||
//shader->set_uniform("print_volume.xy_data", m_render_volume.data);
|
||||
//shader->set_uniform("print_volume.z_data", m_render_volume.zs);
|
||||
if (printable_heights) {
|
||||
std::array<float, 3> extruder_printable_heights;
|
||||
if ((*printable_heights).size() > 0) {
|
||||
extruder_printable_heights[0] = 2.0f;
|
||||
extruder_printable_heights[1] = (*printable_heights)[0];
|
||||
extruder_printable_heights[2] = (*printable_heights)[1];
|
||||
shader->set_uniform("extruder_printable_heights", extruder_printable_heights);
|
||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||
} else {
|
||||
extruder_printable_heights[0] = 0.0f;
|
||||
shader->set_uniform("extruder_printable_heights", extruder_printable_heights);
|
||||
//BBS set print_volume to render volume
|
||||
//shader->set_uniform("print_volume.type", static_cast<int>(m_render_volume.type));
|
||||
//shader->set_uniform("print_volume.xy_data", m_render_volume.data);
|
||||
//shader->set_uniform("print_volume.z_data", m_render_volume.zs);
|
||||
if (printable_heights) {
|
||||
std::array<float, 3> extruder_printable_heights;
|
||||
if ((*printable_heights).size() > 0) {
|
||||
extruder_printable_heights[0] = 2.0f;
|
||||
extruder_printable_heights[1] = (*printable_heights)[0];
|
||||
extruder_printable_heights[2] = (*printable_heights)[1];
|
||||
shader->set_uniform("extruder_printable_heights", extruder_printable_heights);
|
||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||
}
|
||||
else {
|
||||
extruder_printable_heights[0] = 0.0f;
|
||||
shader->set_uniform("extruder_printable_heights", extruder_printable_heights);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (volume.first->partly_inside && partly_inside_enable) {
|
||||
//only partly inside volume need to be painted with boundary check
|
||||
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
||||
shader->set_uniform("print_volume.z_data", m_print_volume.zs);
|
||||
if (!printable_heights || (printable_heights && (*printable_heights).size() == 0)) {
|
||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||
if (volume.first->partly_inside && partly_inside_enable) {
|
||||
//only partly inside volume need to be painted with boundary check
|
||||
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
||||
shader->set_uniform("print_volume.z_data", m_print_volume.zs);
|
||||
if (!printable_heights || (printable_heights && (*printable_heights).size() == 0)) {
|
||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//use -1 ad a invalid type
|
||||
shader->set_uniform("print_volume.type", -1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//use -1 ad a invalid type
|
||||
shader->set_uniform("print_volume.type", -1);
|
||||
}
|
||||
|
||||
bool enable_support;
|
||||
int support_threshold_angle = get_selection_support_threshold_angle(enable_support);
|
||||
bool enable_support;
|
||||
int support_threshold_angle = get_selection_support_threshold_angle(enable_support);
|
||||
|
||||
float normal_z = -::cos(Geometry::deg2rad((float) support_threshold_angle));
|
||||
float normal_z = -::cos(Geometry::deg2rad((float)support_threshold_angle));
|
||||
|
||||
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
|
||||
shader->set_uniform("slope.actived", m_slope.isGlobalActive && !volume.first->is_modifier && !volume.first->is_wipe_tower);
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
||||
shader->set_uniform("slope.normal_z", normal_z);
|
||||
shader->set_uniform("volume_world_matrix", volume.first->world_matrix());
|
||||
shader->set_uniform("slope.actived", m_slope.isGlobalActive && !volume.first->is_modifier && !volume.first->is_wipe_tower);
|
||||
shader->set_uniform("slope.volume_world_normal_matrix", static_cast<Matrix3f>(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast<float>()));
|
||||
shader->set_uniform("slope.normal_z", normal_z);
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
|
||||
shader->set_uniform("use_environment_tex", use_environment_texture);
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
|
||||
unsigned int environment_texture_id = GUI::wxGetApp().plater()->get_environment_texture_id();
|
||||
bool use_environment_texture = environment_texture_id > 0 && GUI::wxGetApp().app_config->get("use_environment_map") == "1";
|
||||
shader->set_uniform("use_environment_tex", use_environment_texture);
|
||||
if (use_environment_texture)
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, environment_texture_id));
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
glcheck();
|
||||
glcheck();
|
||||
|
||||
//BBS: add outline related logic
|
||||
auto red_color = std::array<float, 4>({1.0f, 0.0f, 0.0f, 1.0f});//slice_error
|
||||
volume.first->render(with_outline && volume.first->selected, volume.first->slice_error ? red_color : body_color);
|
||||
//BBS: add outline related logic
|
||||
auto red_color = std::array<float, 4>({ 1.0f, 0.0f, 0.0f, 1.0f });//slice_error
|
||||
volume.first->render(with_outline&& volume.first->selected, volume.first->slice_error ? red_color : body_color);
|
||||
}
|
||||
else {
|
||||
if (volume.first->selected) {
|
||||
shader->set_uniform("u_model_matrix", volume.first->world_matrix());
|
||||
volume.first->render(false, body_color);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_ENVIRONMENT_MAP
|
||||
if (use_environment_texture)
|
||||
|
@ -1683,16 +1695,18 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
|||
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
|
||||
}
|
||||
|
||||
if (m_show_sinking_contours) {
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
// render sinking contours of hovered/displaced volumes
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
|
||||
shader->stop_using();
|
||||
glsafe(::glDepthFunc(GL_ALWAYS));
|
||||
volume.first->render_sinking_contours();
|
||||
glsafe(::glDepthFunc(GL_LESS));
|
||||
shader->start_using();
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
if (m_show_sinking_contours) {
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
// render sinking contours of hovered/displaced volumes
|
||||
if (volume.first->is_sinking() && !volume.first->is_below_printbed() &&
|
||||
(volume.first->hover != GLVolume::HS_None || volume.first->force_sinking_contours)) {
|
||||
shader->stop_using();
|
||||
glsafe(::glDepthFunc(GL_ALWAYS));
|
||||
volume.first->render_sinking_contours();
|
||||
glsafe(::glDepthFunc(GL_LESS));
|
||||
shader->start_using();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include "MeshUtils.hpp"
|
||||
#include "GLShader.hpp"
|
||||
#include "GLEnums.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
@ -725,7 +726,8 @@ public:
|
|||
int get_selection_support_threshold_angle(bool&) const;
|
||||
// Render the volumes by OpenGL.
|
||||
//BBS: add outline drawing logic
|
||||
void render(ERenderType type,
|
||||
void render(GUI::ERenderPipelineStage render_pipeline_stage,
|
||||
ERenderType type,
|
||||
bool disable_cullface,
|
||||
const Transform3d & view_matrix,
|
||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(),
|
||||
|
|
|
@ -4198,7 +4198,7 @@ void GCodeViewer::render_shells()
|
|||
|
||||
shader->start_using();
|
||||
//BBS: reopen cul faces
|
||||
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
|
||||
m_shells.volumes.render(GUI::ERenderPipelineStage::Normal, GLVolumeCollection::ERenderType::Transparent, false, wxGetApp().plater()->get_camera().get_view_matrix());
|
||||
shader->stop_using();
|
||||
|
||||
glsafe(::glDepthMask(GL_TRUE));
|
||||
|
|
|
@ -1181,6 +1181,8 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
|||
m_assembly_view_desc["part_selection"] = _L("part selection");
|
||||
m_assembly_view_desc["number_key_caption"] = "1~16 " + _L("number keys");
|
||||
m_assembly_view_desc["number_key"] = _L("number keys can quickly change the color of objects");
|
||||
|
||||
m_render_pipeline_stage_stack.push(ERenderPipelineStage::Normal);
|
||||
}
|
||||
|
||||
GLCanvas3D::~GLCanvas3D()
|
||||
|
@ -1920,6 +1922,8 @@ void GLCanvas3D::render(bool only_init)
|
|||
return;
|
||||
}
|
||||
|
||||
wxGetApp().set_picking_effect(EPickingEffect::Silhouette);
|
||||
|
||||
if (only_init)
|
||||
return;
|
||||
|
||||
|
@ -1962,6 +1966,10 @@ void GLCanvas3D::render(bool only_init)
|
|||
GLfloat position_top[4] = { -0.5f, -0.5f, 1.0f, 0.0f };
|
||||
glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top));
|
||||
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
auto& ogl_manager = wxGetApp().get_opengl_manager();
|
||||
ogl_manager.set_viewport_size(viewport[2], viewport[3]);
|
||||
|
||||
wxGetApp().imgui()->new_frame();
|
||||
|
||||
if (m_picking_enabled) {
|
||||
|
@ -2002,20 +2010,27 @@ void GLCanvas3D::render(bool only_init)
|
|||
|
||||
/* view3D render*/
|
||||
int hover_id = (m_hover_plate_idxs.size() > 0)?m_hover_plate_idxs.front():-1;
|
||||
EPickingEffect picking_effect = wxGetApp().get_picking_effect();
|
||||
if (EPickingEffect::Disabled != picking_effect) {
|
||||
if (!ogl_manager.are_framebuffers_supported()) {
|
||||
picking_effect = EPickingEffect::StencilOutline; // use stencil outline as framebuffer not supported yet.
|
||||
}
|
||||
}
|
||||
bool b_with_stencil_outline = !m_gizmos.is_running() && (EPickingEffect::StencilOutline == picking_effect);
|
||||
if (m_canvas_type == ECanvasType::CanvasView3D) {
|
||||
//BBS: add outline logic
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, b_with_stencil_outline);
|
||||
_render_sla_slices();
|
||||
_render_selection();
|
||||
if (!no_partplate)
|
||||
_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
if (!no_partplate) //BBS: add outline logic
|
||||
_render_platelist(!camera.is_looking_downward(), only_current, only_body, hover_id, true, show_grid);
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running());
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, b_with_stencil_outline);
|
||||
}
|
||||
/* preview render */
|
||||
else if (m_canvas_type == ECanvasType::CanvasPreview && m_render_preview) {
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, b_with_stencil_outline);
|
||||
_render_sla_slices();
|
||||
_render_selection();
|
||||
_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
|
@ -2029,13 +2044,17 @@ void GLCanvas3D::render(bool only_init)
|
|||
if (m_show_world_axes) {
|
||||
m_axes.render();
|
||||
}
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, b_with_stencil_outline);
|
||||
//_render_bed(!camera.is_looking_downward(), show_axes);
|
||||
_render_plane();
|
||||
//BBS: add outline logic insteadof selection under assemble view
|
||||
//_render_selection();
|
||||
// BBS: add outline logic
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, !m_gizmos.is_running());
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, b_with_stencil_outline);
|
||||
}
|
||||
|
||||
if (EPickingEffect::Silhouette == picking_effect) {
|
||||
_render_silhouette_effect();
|
||||
}
|
||||
|
||||
_render_sequential_clearance();
|
||||
|
@ -2149,6 +2168,7 @@ void GLCanvas3D::render(bool only_init)
|
|||
|
||||
wxGetApp().imgui()->render();
|
||||
|
||||
ogl_manager.clear_dirty();
|
||||
m_canvas->SwapBuffers();
|
||||
m_render_stats.increment_fps_counter();
|
||||
}
|
||||
|
@ -2175,8 +2195,11 @@ void GLCanvas3D::render_thumbnail(ThumbnailData& thumbnail_data, unsigned int w,
|
|||
GLShaderProgram* shader = wxGetApp().get_shader("thumbnail");
|
||||
ModelObjectPtrs& model_objects = GUI::wxGetApp().model().objects;
|
||||
std::vector<std::array<float, 4>> colors = ::get_extruders_colors();
|
||||
switch (OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << boost::format("framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case OpenGLManager::EFramebufferType::Supported:
|
||||
case OpenGLManager::EFramebufferType::Arb:
|
||||
{ render_thumbnail_framebuffer(thumbnail_data, w, h, thumbnail_params, wxGetApp().plater()->get_partplate_list(), model_objects, volumes, colors, shader, camera_type,
|
||||
use_top_view, for_picking, ban_light);
|
||||
|
@ -7319,9 +7342,13 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
std::array<float, 4>({1.0f, 1.0f, 1.0f, 1.0f});//white
|
||||
bool partly_inside_enable = canvas_type == ECanvasType::CanvasAssembleView ? false : true;
|
||||
auto printable_height_option = GUI::wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloatsNullable>("extruder_printable_height");
|
||||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
const GUI::ERenderPipelineStage render_pipeline_stage = _get_current_render_stage();
|
||||
|
||||
if ((GUI::ERenderPipelineStage::Silhouette == render_pipeline_stage) || shader != nullptr) {
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage)
|
||||
{
|
||||
shader->start_using();
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
|
@ -7330,9 +7357,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
if (dynamic_cast<GLGizmoPainterBase*>(gm.get_current()) == nullptr)
|
||||
{
|
||||
if (m_picking_enabled && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
|
||||
if (m_picking_enabled && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f) && GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
int object_id = m_layers_editing.last_object_id;
|
||||
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
|
||||
m_volumes.render(render_pipeline_stage, type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [object_id](const GLVolume& volume) {
|
||||
// Which volume to paint without the layer height profile shader?
|
||||
return volume.is_active && (volume.is_modifier || volume.composite_id.object_id != object_id);
|
||||
});
|
||||
|
@ -7347,7 +7374,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
}*/
|
||||
//BBS:add assemble view related logic
|
||||
// do not cull backfaces to show broken geometry, if any
|
||||
m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
m_volumes.render(render_pipeline_stage, type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier && !volume.is_wipe_tower;
|
||||
}
|
||||
|
@ -7358,7 +7385,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
with_outline, body_color, partly_inside_enable, printable_height_option ? &printable_height_option->values : nullptr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
// In case a painting gizmo is open, it should render the painted triangles
|
||||
// before transparent objects are rendered. Otherwise they would not be
|
||||
// visible when inside modifier meshes etc.
|
||||
|
@ -7381,7 +7408,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
shader->set_uniform("show_wireframe", false);
|
||||
}*/
|
||||
//BBS:add assemble view related logic
|
||||
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
m_volumes.render(render_pipeline_stage, type, false, wxGetApp().plater()->get_camera().get_view_matrix(), [this, canvas_type](const GLVolume& volume) {
|
||||
if (canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
return !volume.is_modifier;
|
||||
}
|
||||
|
@ -7390,7 +7417,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
}
|
||||
},
|
||||
with_outline, body_color, partly_inside_enable, printable_height_option ? &printable_height_option->values : nullptr);
|
||||
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) {
|
||||
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0 && GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
const GLGizmosManager& gm = get_gizmos_manager();
|
||||
shader->stop_using();
|
||||
gm.render_painter_assemble_view();
|
||||
|
@ -7404,7 +7431,9 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
|||
shader->set_uniform("show_wireframe", false);
|
||||
}*/
|
||||
|
||||
shader->stop_using();
|
||||
if (GUI::ERenderPipelineStage::Silhouette != render_pipeline_stage) {
|
||||
shader->stop_using();
|
||||
}
|
||||
}
|
||||
|
||||
m_camera_clipping_plane = ClippingPlane::ClipsNothing();
|
||||
|
@ -9712,6 +9741,151 @@ std::vector<std::array<float, 4>> GLCanvas3D::_parse_colors(const std::vector<st
|
|||
return output;
|
||||
}
|
||||
|
||||
void GLCanvas3D::_push_render_stage(ERenderPipelineStage stage)
|
||||
{
|
||||
m_render_pipeline_stage_stack.push(stage);
|
||||
}
|
||||
|
||||
void GLCanvas3D::_pop_render_stage()
|
||||
{
|
||||
if (m_render_pipeline_stage_stack.size() > 1)
|
||||
{
|
||||
m_render_pipeline_stage_stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
ERenderPipelineStage GLCanvas3D::_get_current_render_stage() const
|
||||
{
|
||||
return m_render_pipeline_stage_stack.top();
|
||||
}
|
||||
|
||||
void GLCanvas3D::_render_silhouette_effect()
|
||||
{;
|
||||
RenderPipelineStageModifier render_pipeline_stage_modifier(*this, ERenderPipelineStage::Silhouette);
|
||||
|
||||
auto& ogl_manager = wxGetApp().get_opengl_manager();
|
||||
|
||||
{
|
||||
// BBS: render silhouette
|
||||
OpenGLManager::FrameBufferModifier frame_buffer_modifier(ogl_manager, "silhouette");
|
||||
|
||||
glsafe(::glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
glsafe(::glClearDepth(1.0f));
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
|
||||
|
||||
GLShaderProgram* p_silhouette_shader = wxGetApp().get_shader("silhouette");
|
||||
if (!p_silhouette_shader)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Invalid shader: silhouette. Failed to render highlight effect.";
|
||||
return;
|
||||
}
|
||||
|
||||
p_silhouette_shader->start_using();
|
||||
|
||||
std::array<float, 4> picking_color{ 1.0f, 0.36f, 0.0f, 1.0f };
|
||||
if (m_canvas_type == ECanvasType::CanvasAssembleView) {
|
||||
picking_color[0] = 1.0f;
|
||||
picking_color[1] = 1.0f;
|
||||
picking_color[2] = 0.0f;
|
||||
picking_color[3] = 1.0f;
|
||||
}
|
||||
else {
|
||||
picking_color[0] = 1.0f;
|
||||
picking_color[1] = 1.0f;
|
||||
picking_color[2] = 1.0f;
|
||||
picking_color[3] = 1.0f;
|
||||
}
|
||||
p_silhouette_shader->set_uniform("u_base_color", picking_color);
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
const Transform3d& projection_matrix = camera.get_projection_matrix();
|
||||
const Matrix4d view_proj = projection_matrix.matrix() * view_matrix.matrix();
|
||||
p_silhouette_shader->set_uniform("u_view_projection_matrix", view_proj);
|
||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, false);
|
||||
_render_objects(GLVolumeCollection::ERenderType::Transparent, false);
|
||||
|
||||
p_silhouette_shader->stop_using();
|
||||
|
||||
// BBS: end render silhouette
|
||||
}
|
||||
|
||||
// BBS: composite silhouette
|
||||
|
||||
const auto& p_frame_buffer = ogl_manager.get_frame_buffer("silhouette");
|
||||
if (!p_frame_buffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto color_texture_id = p_frame_buffer->get_color_texture();
|
||||
if (!p_frame_buffer->is_texture_valid(color_texture_id))
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Invalid framebuffer. Failed to render highlight effect.";
|
||||
return;
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
GLShaderProgram* p_silhouette_composite_shader = wxGetApp().get_shader("silhouette_composite");
|
||||
if (!p_silhouette_composite_shader)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Invalid silhouette texture. Failed to render highlight effect.";
|
||||
return;
|
||||
}
|
||||
p_silhouette_composite_shader->start_using();
|
||||
|
||||
uint32_t viewport_width = 0;
|
||||
uint32_t viewport_height = 0;
|
||||
ogl_manager.get_viewport_size(viewport_width, viewport_height);
|
||||
const std::array<float, 2> viewport_size{ static_cast<float>(viewport_width), static_cast<float>(viewport_height)};
|
||||
p_silhouette_composite_shader->set_uniform("u_viewport_size", viewport_size);
|
||||
|
||||
Matrix3f convolution_matrix;
|
||||
convolution_matrix.data()[3 * 0 + 0] = -0.4f;
|
||||
convolution_matrix.data()[3 * 0 + 1] = -0.4f;
|
||||
convolution_matrix.data()[3 * 0 + 2] = -0.4f;
|
||||
|
||||
convolution_matrix.data()[3 * 1 + 0] = -0.4f;
|
||||
convolution_matrix.data()[3 * 1 + 1] = 3.6f;
|
||||
convolution_matrix.data()[3 * 1 + 2] = -0.4f;
|
||||
|
||||
convolution_matrix.data()[3 * 2 + 0] = -0.4f;
|
||||
convolution_matrix.data()[3 * 2 + 1] = -0.4f;
|
||||
convolution_matrix.data()[3 * 2 + 2] = -0.4f;
|
||||
p_silhouette_composite_shader->set_uniform("u_convolution_matrix", convolution_matrix);
|
||||
|
||||
const int stage = 0;
|
||||
p_silhouette_composite_shader->set_uniform("u_sampler", stage);
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0 + stage));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, color_texture_id));
|
||||
|
||||
if (!m_full_screen_mesh.is_initialized()) {
|
||||
GLModel::Geometry geo;
|
||||
geo.format.type = GLModel::PrimitiveType::Triangles;
|
||||
geo.format.vertex_layout = GLModel::Geometry::EVertexLayout::P3T2;
|
||||
|
||||
geo.add_vertex(Vec3f{ -1.0f, -1.0f, 0.0f }, Vec2f{ 0.0f, 0.0f });
|
||||
geo.add_vertex(Vec3f{ 3.0f, -1.0f, 0.0f }, Vec2f{ 2.0f, 0.0f });
|
||||
geo.add_vertex(Vec3f{ -1.0f, 3.0f, 0.0f }, Vec2f{ 0.0f, 2.0f });
|
||||
|
||||
geo.add_triangle(0, 1, 2);
|
||||
|
||||
m_full_screen_mesh.init_from(std::move(geo));
|
||||
}
|
||||
|
||||
m_full_screen_mesh.render_geometry();
|
||||
|
||||
p_silhouette_composite_shader->stop_using();
|
||||
|
||||
glsafe(::glDisable(GL_BLEND));
|
||||
// BBS: end composite silhouette
|
||||
}
|
||||
|
||||
void GLCanvas3D::_set_warning_notification(EWarning warning, bool state)
|
||||
{
|
||||
enum ErrorType{
|
||||
|
@ -10137,6 +10311,17 @@ void GLCanvas3D::GizmoHighlighterTimer::Notify()
|
|||
wxPostEvent((wxEvtHandler*)GetOwner(), GizmoHighlighterTimerEvent(EVT_GLCANVAS_GIZMO_HIGHLIGHTER_TIMER, *this));
|
||||
}
|
||||
|
||||
GLCanvas3D::RenderPipelineStageModifier::RenderPipelineStageModifier(GLCanvas3D& canvas, ERenderPipelineStage stage)
|
||||
: m_canvas(canvas)
|
||||
{
|
||||
m_canvas._push_render_stage(stage);
|
||||
}
|
||||
|
||||
GLCanvas3D::RenderPipelineStageModifier::~RenderPipelineStageModifier()
|
||||
{
|
||||
m_canvas._pop_render_stage();
|
||||
}
|
||||
|
||||
void GLCanvas3D::ToolbarHighlighter::set_timer_owner(wxEvtHandler* owner, int timerid/* = wxID_ANY*/)
|
||||
{
|
||||
m_timer.SetOwner(owner, timerid);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <stack>
|
||||
|
||||
#include "GLToolbar.hpp"
|
||||
#include "Event.hpp"
|
||||
|
@ -19,6 +20,7 @@
|
|||
#include "IMToolbar.hpp"
|
||||
#include "slic3r/GUI/3DBed.hpp"
|
||||
#include "libslic3r/Slicing.hpp"
|
||||
#include "GLEnums.hpp"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
@ -471,6 +473,25 @@ class GLCanvas3D
|
|||
virtual void Notify() override;
|
||||
};
|
||||
|
||||
class RenderPipelineStageModifier
|
||||
{
|
||||
public:
|
||||
explicit RenderPipelineStageModifier(GLCanvas3D& canvas, ERenderPipelineStage stage);
|
||||
~RenderPipelineStageModifier();
|
||||
|
||||
private:
|
||||
// no copy
|
||||
RenderPipelineStageModifier(const RenderPipelineStageModifier&) = delete;
|
||||
RenderPipelineStageModifier(RenderPipelineStageModifier&&) = delete;
|
||||
|
||||
// no assign
|
||||
RenderPipelineStageModifier& operator=(const RenderPipelineStageModifier&) = delete;
|
||||
RenderPipelineStageModifier& operator=(RenderPipelineStageModifier&&) = delete;
|
||||
private:
|
||||
GLCanvas3D& m_canvas;
|
||||
ERenderPipelineStage m_stage;
|
||||
};
|
||||
|
||||
public:
|
||||
enum ECursorType : unsigned char
|
||||
{
|
||||
|
@ -628,6 +649,9 @@ private:
|
|||
int custom_height_count = 0;
|
||||
int assembly_view_count = 0;
|
||||
|
||||
std::stack<ERenderPipelineStage> m_render_pipeline_stage_stack;
|
||||
GLModel m_full_screen_mesh;
|
||||
|
||||
public:
|
||||
OrientSettings& get_orient_settings()
|
||||
{
|
||||
|
@ -1239,6 +1263,12 @@ private:
|
|||
float get_overlay_window_width() { return 0; /*LayersEditing::get_overlay_window_width();*/ }
|
||||
|
||||
static std::vector<std::array<float, 4>> _parse_colors(const std::vector<std::string>& colors);
|
||||
|
||||
void _push_render_stage(ERenderPipelineStage stage);
|
||||
void _pop_render_stage();
|
||||
ERenderPipelineStage _get_current_render_stage() const;
|
||||
|
||||
void _render_silhouette_effect();
|
||||
};
|
||||
|
||||
const ModelVolume *get_model_volume(const GLVolume &v, const Model &model);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef slic3r_GUI_GLEnums_hpp_
|
||||
#define slic3r_GUI_GLEnums_hpp_
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
enum class EPickingEffect
|
||||
{
|
||||
Disabled,
|
||||
StencilOutline,
|
||||
Silhouette
|
||||
};
|
||||
|
||||
enum class ERenderPipelineStage
|
||||
{
|
||||
Normal,
|
||||
Silhouette
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
} // namespace GUI
|
||||
|
||||
#endif // slic3r_GUI_GLEnums_hpp_
|
|
@ -349,6 +349,21 @@ bool GLShaderProgram::set_uniform(const char *name, const Matrix3d &value) const
|
|||
return set_uniform(name, (Matrix3f) value.cast<float>());
|
||||
}
|
||||
|
||||
bool GLShaderProgram::set_uniform(const char* name, const Matrix4f& value) const
|
||||
{
|
||||
int id = get_uniform_location(name);
|
||||
if (id >= 0) {
|
||||
glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GLShaderProgram::set_uniform(const char* name, const Matrix4d& value) const
|
||||
{
|
||||
return set_uniform(name, (Matrix4f)value.cast<float>());
|
||||
}
|
||||
|
||||
bool GLShaderProgram::set_uniform(const char* name, const Vec3f& value) const
|
||||
{
|
||||
int id = get_uniform_location(name);
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
bool set_uniform(const char* name, const Transform3d& value) const;
|
||||
bool set_uniform(const char* name, const Matrix3f& value) const;
|
||||
bool set_uniform(const char *name, const Matrix3d &value) const;
|
||||
bool set_uniform(const char* name, const Matrix4f& value) const;
|
||||
bool set_uniform(const char* name, const Matrix4d& value) const;
|
||||
bool set_uniform(const char* name, const Vec3f& value) const;
|
||||
bool set_uniform(const char* name, const Vec3d& value) const;
|
||||
|
||||
|
|
|
@ -92,6 +92,10 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
//BBS: add shader for outline
|
||||
valid &= append_shader("outline", { "outline.vs", "outline.fs" });
|
||||
|
||||
valid &= append_shader("silhouette", { "110/silhouette.vs", "110/silhouette.fs" });
|
||||
|
||||
valid &= append_shader("silhouette_composite", { "110/silhouette_composite.vs", "110/silhouette_composite.fs" });
|
||||
|
||||
return { valid, error };
|
||||
}
|
||||
|
||||
|
|
|
@ -7071,6 +7071,32 @@ void GUI_App::check_config_updates_from_menu()
|
|||
check_updates(true);
|
||||
}
|
||||
|
||||
void GUI_App::set_picking_effect(EPickingEffect effect)
|
||||
{
|
||||
if (m_picking_effect != effect)
|
||||
{
|
||||
std::string str_picking_effect{};
|
||||
switch (effect)
|
||||
{
|
||||
case EPickingEffect::Disabled:
|
||||
str_picking_effect = "Disabled";
|
||||
break;
|
||||
case EPickingEffect::StencilOutline:
|
||||
str_picking_effect = "StencilOutline";
|
||||
break;
|
||||
case EPickingEffect::Silhouette:
|
||||
str_picking_effect = "Silhouette";
|
||||
break;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(info) << "Switched picking effect to: " << str_picking_effect;
|
||||
m_picking_effect = effect;
|
||||
}
|
||||
}
|
||||
|
||||
EPickingEffect GUI_App::get_picking_effect() const
|
||||
{
|
||||
return m_picking_effect;
|
||||
}
|
||||
|
||||
bool GUI_App::open_browser_with_warning_dialog(const wxString& url, int flags/* = 0*/)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "slic3r/GUI/Jobs/UpgradeNetworkJob.hpp"
|
||||
#include "slic3r/GUI/HttpServer.hpp"
|
||||
#include "../Utils/PrintHost.hpp"
|
||||
#include "slic3r/GUI/GLEnums.hpp"
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/colour.h>
|
||||
|
@ -659,6 +660,9 @@ public:
|
|||
void check_config_updates_from_updater();
|
||||
void check_config_updates_from_menu();
|
||||
|
||||
void set_picking_effect(EPickingEffect effect);
|
||||
EPickingEffect get_picking_effect() const;
|
||||
|
||||
private:
|
||||
int updating_bambu_networking();
|
||||
bool on_init_inner();
|
||||
|
@ -687,6 +691,7 @@ private:
|
|||
std::string m_older_data_dir_path;
|
||||
boost::optional<Semver> m_last_config_version;
|
||||
std::string m_open_method;
|
||||
EPickingEffect m_picking_effect{ EPickingEffect::StencilOutline };
|
||||
};
|
||||
|
||||
DECLARE_APP(GUI_App)
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
#include "../Utils/MacDarkMode.hpp"
|
||||
#endif // __APPLE__
|
||||
|
||||
#define BBS_GL_EXTENSION_FUNC(_func) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _func ## EXT : _func)
|
||||
#define BBS_GL_EXTENSION_FRAMEBUFFER OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? GL_FRAMEBUFFER_EXT : GL_FRAMEBUFFER
|
||||
#define BBS_GL_EXTENSION_COLOR_ATTACHMENT(color_attachment) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? color_attachment ## _EXT : color_attachment)
|
||||
#define BBS_GL_EXTENSION_DEPTH_ATTACHMENT OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? GL_DEPTH_ATTACHMENT_EXT : GL_DEPTH_ATTACHMENT
|
||||
#define BBS_GL_EXTENSION_RENDER_BUFFER OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? GL_RENDERBUFFER_EXT : GL_RENDERBUFFER
|
||||
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
|
||||
|
@ -41,6 +48,20 @@ const std::string& OpenGLManager::GLInfo::get_version() const
|
|||
return m_version;
|
||||
}
|
||||
|
||||
const uint32_t OpenGLManager::GLInfo::get_formated_gl_version() const
|
||||
{
|
||||
if (0 == m_formated_gl_version)
|
||||
{
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
|
||||
m_formated_gl_version = major * 10 + minor;
|
||||
}
|
||||
return m_formated_gl_version;
|
||||
}
|
||||
|
||||
const std::string& OpenGLManager::GLInfo::get_glsl_version() const
|
||||
{
|
||||
if (!m_detected)
|
||||
|
@ -219,6 +240,7 @@ OpenGLManager::OSInfo OpenGLManager::s_os_info;
|
|||
OpenGLManager::~OpenGLManager()
|
||||
{
|
||||
m_shaders_manager.shutdown();
|
||||
m_name_to_frame_buffer.clear();
|
||||
|
||||
#ifdef __APPLE__
|
||||
// This is an ugly hack needed to solve the crash happening when closing the application on OSX 10.9.5 with newer wxWidgets
|
||||
|
@ -249,7 +271,13 @@ bool OpenGLManager::init_gl(bool popup_error)
|
|||
else
|
||||
s_compressed_textures_supported = false;
|
||||
|
||||
if (GLEW_ARB_framebuffer_object) {
|
||||
const auto& gl_info = OpenGLManager::get_gl_info();
|
||||
const uint32_t gl_formated_version = gl_info.get_formated_gl_version();
|
||||
if (gl_formated_version >= 30) {
|
||||
s_framebuffers_type = EFramebufferType::Supported;
|
||||
BOOST_LOG_TRIVIAL(info) << "Opengl version >= 30, FrameBuffer normal." << std::endl;
|
||||
}
|
||||
else if (GLEW_ARB_framebuffer_object) {
|
||||
s_framebuffers_type = EFramebufferType::Arb;
|
||||
BOOST_LOG_TRIVIAL(info) << "Found Framebuffer Type ARB."<< std::endl;
|
||||
}
|
||||
|
@ -336,6 +364,78 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas)
|
|||
return m_context;
|
||||
}
|
||||
|
||||
void OpenGLManager::clear_dirty()
|
||||
{
|
||||
m_b_viewport_dirty = false;
|
||||
}
|
||||
|
||||
void OpenGLManager::set_viewport_size(uint32_t width, uint32_t height)
|
||||
{
|
||||
if (width != m_viewport_width)
|
||||
{
|
||||
m_b_viewport_dirty = true;
|
||||
m_viewport_width = width;
|
||||
}
|
||||
if (height != m_viewport_height)
|
||||
{
|
||||
m_b_viewport_dirty = true;
|
||||
m_viewport_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLManager::get_viewport_size(uint32_t& width, uint32_t& height) const
|
||||
{
|
||||
width = m_viewport_width;
|
||||
height = m_viewport_height;
|
||||
}
|
||||
|
||||
void OpenGLManager::_bind_frame_buffer(const std::string& name)
|
||||
{
|
||||
const auto& iter = m_name_to_frame_buffer.find(name);
|
||||
if (iter == m_name_to_frame_buffer.end() || m_b_viewport_dirty) {
|
||||
const auto& p_frame_buffer = std::make_shared<FrameBuffer>(m_viewport_width, m_viewport_height);
|
||||
m_name_to_frame_buffer.insert_or_assign(name, p_frame_buffer);
|
||||
}
|
||||
|
||||
m_name_to_frame_buffer[name]->bind();
|
||||
}
|
||||
|
||||
void OpenGLManager::_unbind_frame_buffer(const std::string& name)
|
||||
{
|
||||
const auto& iter = m_name_to_frame_buffer.find(name);
|
||||
if (iter == m_name_to_frame_buffer.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_name_to_frame_buffer[name]->unbind();
|
||||
}
|
||||
|
||||
const std::shared_ptr<FrameBuffer>& OpenGLManager::get_frame_buffer(const std::string& name) const
|
||||
{
|
||||
const auto& iter = m_name_to_frame_buffer.find(name);
|
||||
if (iter != m_name_to_frame_buffer.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
static std::shared_ptr<FrameBuffer> sEmpty{ nullptr };
|
||||
return sEmpty;
|
||||
}
|
||||
|
||||
std::string OpenGLManager::framebuffer_type_to_string(EFramebufferType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case EFramebufferType::Supported:
|
||||
return "Supported";
|
||||
case EFramebufferType::Arb:
|
||||
return "ARB";
|
||||
case EFramebufferType::Ext:
|
||||
return "EXT";
|
||||
case EFramebufferType::Unknown:
|
||||
default:
|
||||
return "unknow";
|
||||
}
|
||||
}
|
||||
|
||||
wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent)
|
||||
{
|
||||
int attribList[] = {
|
||||
|
@ -383,5 +483,127 @@ void OpenGLManager::detect_multisample(int* attribList)
|
|||
// s_multisample = enable_multisample && wxGLCanvas::IsExtensionSupported("WGL_ARB_multisample");
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer(uint32_t width, uint32_t height)
|
||||
: m_width(width)
|
||||
, m_height(height)
|
||||
{
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
if (UINT32_MAX != m_gl_id)
|
||||
{
|
||||
//glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
glsafe(::glDeleteFramebuffers(1, &m_gl_id));
|
||||
m_gl_id = UINT32_MAX;
|
||||
}
|
||||
|
||||
if (UINT32_MAX != m_color_texture_id)
|
||||
{
|
||||
glDeleteTextures(1, &m_color_texture_id);
|
||||
m_color_texture_id = UINT32_MAX;
|
||||
}
|
||||
|
||||
if (UINT32_MAX != m_depth_rbo_id)
|
||||
{
|
||||
glDeleteRenderbuffers(1, &m_depth_rbo_id);
|
||||
m_depth_rbo_id = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBuffer::bind()
|
||||
{
|
||||
const OpenGLManager::EFramebufferType framebuffer_type = OpenGLManager::get_framebuffers_type();
|
||||
if (OpenGLManager::EFramebufferType::Unknown == framebuffer_type) {
|
||||
return;
|
||||
}
|
||||
if (0 == m_width || 0 == m_height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (UINT32_MAX == m_gl_id)
|
||||
{
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glGenFramebuffers)(1, &m_gl_id));
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, m_gl_id));
|
||||
|
||||
glsafe(::glGenTextures(1, &m_color_texture_id));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, m_color_texture_id));
|
||||
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glFramebufferTexture2D)(BBS_GL_EXTENSION_FRAMEBUFFER, BBS_GL_EXTENSION_COLOR_ATTACHMENT(GL_COLOR_ATTACHMENT0), GL_TEXTURE_2D, m_color_texture_id, 0));
|
||||
|
||||
if (OpenGLManager::EFramebufferType::Ext == framebuffer_type) {
|
||||
GLenum bufs[1]{ GL_COLOR_ATTACHMENT0_EXT };
|
||||
glsafe(::glDrawBuffers((GLsizei)1, bufs));
|
||||
}
|
||||
else {
|
||||
GLenum bufs[1]{ GL_COLOR_ATTACHMENT0 };
|
||||
glsafe(::glDrawBuffers((GLsizei)1, bufs));
|
||||
}
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glGenRenderbuffers)(1, &m_depth_rbo_id));
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindRenderbuffer)(BBS_GL_EXTENSION_RENDER_BUFFER, m_depth_rbo_id));
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glRenderbufferStorage)(BBS_GL_EXTENSION_RENDER_BUFFER, GL_DEPTH24_STENCIL8, m_width, m_height));
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glFramebufferRenderbuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, BBS_GL_EXTENSION_DEPTH_ATTACHMENT, BBS_GL_EXTENSION_RENDER_BUFFER, m_depth_rbo_id));
|
||||
|
||||
if (OpenGLManager::EFramebufferType::Ext == framebuffer_type) {
|
||||
if (::glCheckFramebufferStatusEXT(BBS_GL_EXTENSION_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Framebuffer is not complete!";
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(error) << "Framebuffer is not complete!";
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, 0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(trace) << "Successfully created framebuffer: width = " << m_width << ", heihgt = " << m_height;
|
||||
}
|
||||
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, m_gl_id));
|
||||
}
|
||||
|
||||
void FrameBuffer::unbind()
|
||||
{
|
||||
const OpenGLManager::EFramebufferType framebuffer_type = OpenGLManager::get_framebuffers_type();
|
||||
if (OpenGLManager::EFramebufferType::Unknown == framebuffer_type) {
|
||||
return;
|
||||
}
|
||||
glsafe(BBS_GL_EXTENSION_FUNC(::glBindFramebuffer)(BBS_GL_EXTENSION_FRAMEBUFFER, 0));
|
||||
}
|
||||
|
||||
uint32_t FrameBuffer::get_color_texture() const noexcept
|
||||
{
|
||||
return m_color_texture_id;
|
||||
}
|
||||
|
||||
bool FrameBuffer::is_texture_valid(uint32_t texture_id) const noexcept
|
||||
{
|
||||
return m_color_texture_id != UINT32_MAX;
|
||||
}
|
||||
|
||||
OpenGLManager::FrameBufferModifier::FrameBufferModifier(OpenGLManager& ogl_manager, const std::string& frame_buffer_name)
|
||||
: m_ogl_manager(ogl_manager)
|
||||
, m_frame_buffer_name(frame_buffer_name)
|
||||
{
|
||||
m_ogl_manager._bind_frame_buffer(m_frame_buffer_name);
|
||||
}
|
||||
|
||||
OpenGLManager::FrameBufferModifier::~FrameBufferModifier()
|
||||
{
|
||||
m_ogl_manager._unbind_frame_buffer(m_frame_buffer_name);
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
} // namespace Slic3r
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#define slic3r_OpenGLManager_hpp_
|
||||
|
||||
#include "GLShadersManager.hpp"
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
class wxWindow;
|
||||
class wxGLCanvas;
|
||||
|
@ -11,12 +14,33 @@ namespace Slic3r {
|
|||
namespace GUI {
|
||||
|
||||
|
||||
struct FrameBuffer
|
||||
{
|
||||
FrameBuffer(uint32_t width, uint32_t height);
|
||||
~FrameBuffer();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
uint32_t get_color_texture() const noexcept;
|
||||
|
||||
bool is_texture_valid(uint32_t texture_id) const noexcept;
|
||||
|
||||
private:
|
||||
uint32_t m_width{ 0 };
|
||||
uint32_t m_height{ 0 };
|
||||
uint32_t m_gl_id{ UINT32_MAX };
|
||||
uint32_t m_color_texture_id{ UINT32_MAX };
|
||||
uint32_t m_depth_rbo_id{ UINT32_MAX };
|
||||
};
|
||||
|
||||
class OpenGLManager
|
||||
{
|
||||
public:
|
||||
enum class EFramebufferType : unsigned char
|
||||
{
|
||||
Unknown,
|
||||
Supported, // supported, no extension required
|
||||
Arb,
|
||||
Ext
|
||||
};
|
||||
|
@ -28,6 +52,7 @@ public:
|
|||
float m_max_anisotropy{ 0.0f };
|
||||
|
||||
std::string m_version;
|
||||
mutable uint32_t m_formated_gl_version{ 0 };
|
||||
std::string m_glsl_version;
|
||||
std::string m_vendor;
|
||||
std::string m_renderer;
|
||||
|
@ -36,6 +61,7 @@ public:
|
|||
GLInfo() = default;
|
||||
|
||||
const std::string& get_version() const;
|
||||
const uint32_t get_formated_gl_version() const;
|
||||
const std::string& get_glsl_version() const;
|
||||
const std::string& get_vendor() const;
|
||||
const std::string& get_renderer() const;
|
||||
|
@ -54,6 +80,26 @@ public:
|
|||
void detect() const;
|
||||
};
|
||||
|
||||
class FrameBufferModifier
|
||||
{
|
||||
public:
|
||||
explicit FrameBufferModifier(OpenGLManager& ogl_manager, const std::string& frame_buffer_name);
|
||||
~FrameBufferModifier();
|
||||
|
||||
private:
|
||||
// no copy
|
||||
FrameBufferModifier(const FrameBufferModifier&) = delete;
|
||||
FrameBufferModifier(FrameBufferModifier&&) = delete;
|
||||
|
||||
// no assign
|
||||
FrameBufferModifier& operator=(const FrameBufferModifier&) = delete;
|
||||
FrameBufferModifier& operator=(FrameBufferModifier&&) = delete;
|
||||
|
||||
private:
|
||||
OpenGLManager& m_ogl_manager;
|
||||
std::string m_frame_buffer_name{};
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
|
||||
struct OSInfo
|
||||
|
@ -75,6 +121,10 @@ private:
|
|||
bool m_gl_initialized{ false };
|
||||
wxGLContext* m_context{ nullptr };
|
||||
GLShadersManager m_shaders_manager;
|
||||
uint32_t m_viewport_width{ 0 };
|
||||
uint32_t m_viewport_height{ 0 };
|
||||
bool m_b_viewport_dirty{ true };
|
||||
std::unordered_map<std::string, std::shared_ptr<FrameBuffer>> m_name_to_frame_buffer;
|
||||
static GLInfo s_gl_info;
|
||||
#ifdef __APPLE__
|
||||
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
|
||||
|
@ -95,16 +145,24 @@ public:
|
|||
GLShaderProgram* get_shader(const std::string& shader_name) { return m_shaders_manager.get_shader(shader_name); }
|
||||
GLShaderProgram* get_current_shader() { return m_shaders_manager.get_current_shader(); }
|
||||
|
||||
void clear_dirty();
|
||||
void set_viewport_size(uint32_t width, uint32_t height);
|
||||
void get_viewport_size(uint32_t& width, uint32_t& height) const;
|
||||
const std::shared_ptr<FrameBuffer>& get_frame_buffer(const std::string& name) const;
|
||||
|
||||
static bool are_compressed_textures_supported() { return s_compressed_textures_supported; }
|
||||
static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; }
|
||||
static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }
|
||||
static EFramebufferType get_framebuffers_type() { return s_framebuffers_type; }
|
||||
static std::string framebuffer_type_to_string(EFramebufferType type);
|
||||
static wxGLCanvas* create_wxglcanvas(wxWindow& parent);
|
||||
static const GLInfo& get_gl_info() { return s_gl_info; }
|
||||
static bool use_manually_generated_mipmaps() { return m_use_manually_generated_mipmaps; }
|
||||
|
||||
private:
|
||||
static void detect_multisample(int* attribList);
|
||||
void _bind_frame_buffer(const std::string& name);
|
||||
void _unbind_frame_buffer(const std::string& name);
|
||||
};
|
||||
|
||||
} // namespace GUI
|
||||
|
|
|
@ -1315,11 +1315,13 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
|||
}
|
||||
}
|
||||
|
||||
switch (Slic3r::GUI::OpenGLManager::get_framebuffers_type())
|
||||
const auto fb_type = Slic3r::GUI::OpenGLManager::get_framebuffers_type();
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": framebuffer_type: %1%") % Slic3r::GUI::OpenGLManager::framebuffer_type_to_string(fb_type).c_str();
|
||||
switch (fb_type)
|
||||
{
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Supported:
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Arb:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": framebuffer_type: ARB");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
|
@ -1327,14 +1329,12 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
|
|||
}
|
||||
case Slic3r::GUI::OpenGLManager::EFramebufferType::Ext:
|
||||
{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": framebuffer_type: EXT");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_framebuffer_ext(*thumbnail_data,
|
||||
thumbnail_width, thumbnail_height, thumbnail_params,
|
||||
partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": framebuffer_type: others");
|
||||
Slic3r::GUI::GLCanvas3D::render_thumbnail_legacy(*thumbnail_data, thumbnail_width, thumbnail_height, thumbnail_params, partplate_list, model->objects, glvolume_collection, colors_out, shader, Slic3r::GUI::Camera::EType::Ortho);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue