diff --git a/resources/shaders/background.fs b/resources/shaders/background.fs new file mode 100644 index 0000000000..b148440898 --- /dev/null +++ b/resources/shaders/background.fs @@ -0,0 +1,11 @@ +#version 110 + +uniform vec4 top_color; +uniform vec4 bottom_color; + +varying vec2 tex_coord; + +void main() +{ + gl_FragColor = mix(bottom_color, top_color, tex_coord.y); +} diff --git a/resources/shaders/background.vs b/resources/shaders/background.vs new file mode 100644 index 0000000000..b7c1d92c0e --- /dev/null +++ b/resources/shaders/background.vs @@ -0,0 +1,9 @@ +#version 110 + +varying vec2 tex_coord; + +void main() +{ + gl_Position = gl_Vertex; + tex_coord = gl_MultiTexCoord0.xy; +} diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 8d279c419a..5e342ec85e 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -78,26 +78,19 @@ static constexpr const float TRACKBALLSIZE = 0.8f; -static Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR = {0.906f, 0.906f, 0.906f}; -static Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR_DARK = {0.329f, 0.329f, 0.353f}; -static Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR = {0.753f, 0.192f, 0.039f}; -static Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR_DARK = {0.753f, 0.192f, 0.039f}; +static Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.906f, 0.906f, 0.906f, 1.0f }; +static Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR_DARK = { 0.329f, 0.329f, 0.353f, 1.0f }; +static Slic3r::ColorRGBA ERROR_BG_LIGHT_COLOR = { 0.753f, 0.192f, 0.039f, 1.0f }; +static Slic3r::ColorRGBA ERROR_BG_LIGHT_COLOR_DARK = { 0.753f, 0.192f, 0.039f, 1.0f }; void GLCanvas3D::update_render_colors() { - DEFAULT_BG_LIGHT_COLOR = { - RenderColor::colors[RenderCol_3D_Background].x, - RenderColor::colors[RenderCol_3D_Background].y, - RenderColor::colors[RenderCol_3D_Background].z, - }; + DEFAULT_BG_LIGHT_COLOR = ImGuiWrapper::from_ImVec4(RenderColor::colors[RenderCol_3D_Background]); } void GLCanvas3D::load_render_colors() { - RenderColor::colors[RenderCol_3D_Background] = ImVec4(DEFAULT_BG_LIGHT_COLOR.r(), - DEFAULT_BG_LIGHT_COLOR.g(), - DEFAULT_BG_LIGHT_COLOR.b(), - 1.0f); + RenderColor::colors[RenderCol_3D_Background] = ImGuiWrapper::to_ImVec4(DEFAULT_BG_LIGHT_COLOR); } //static constexpr const float AXES_COLOR[3][3] = { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } }; @@ -6610,7 +6603,7 @@ void GLCanvas3D::_rectangular_selection_picking_pass() _update_volumes_hover_state(); } -void GLCanvas3D::_render_background() const +void GLCanvas3D::_render_background() { bool use_error_color = false; if (wxGetApp().is_editor()) { @@ -6642,27 +6635,41 @@ void GLCanvas3D::_render_background() const // Draws a bottom to top gradient over the complete screen. glsafe(::glDisable(GL_DEPTH_TEST)); - ::glBegin(GL_QUADS); + ColorRGBA background_color = m_is_dark ? DEFAULT_BG_LIGHT_COLOR_DARK : DEFAULT_BG_LIGHT_COLOR; + ColorRGBA error_background_color = m_is_dark ? ERROR_BG_LIGHT_COLOR_DARK : ERROR_BG_LIGHT_COLOR; + const ColorRGBA bottom_color = use_error_color ? error_background_color : background_color; - ColorRGB background_color = m_is_dark ? DEFAULT_BG_LIGHT_COLOR_DARK : DEFAULT_BG_LIGHT_COLOR; - ColorRGB error_background_color = m_is_dark ? ERROR_BG_LIGHT_COLOR_DARK : ERROR_BG_LIGHT_COLOR; + if (!m_background.is_initialized() || m_background.get_color() != bottom_color) { + m_background.reset(); - if (use_error_color) - ::glColor3fv(error_background_color.data()); - else - ::glColor3fv(background_color.data()); + GLModel::Geometry init_data; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT }; + init_data.color = bottom_color; + init_data.vertices.reserve(4 * GLModel::Geometry::vertex_stride_floats(init_data.format)); + init_data.indices.reserve(6 * GLModel::Geometry::index_stride_bytes(init_data.format)); - ::glVertex2f(-1.0f, -1.0f); - ::glVertex2f(1.0f, -1.0f); + // vertices + init_data.add_vertex(Vec2f(-1.0f, -1.0f), Vec2f(0.0f, 0.0f)); + init_data.add_vertex(Vec2f(1.0f, -1.0f), Vec2f(1.0f, 0.0f)); + init_data.add_vertex(Vec2f(1.0f, 1.0f), Vec2f(1.0f, 1.0f)); + init_data.add_vertex(Vec2f(-1.0f, 1.0f), Vec2f(0.0f, 1.0f)); - if (use_error_color) - ::glColor3fv(error_background_color.data()); - else - ::glColor3fv(background_color.data()); + // indices + init_data.add_ushort_triangle(0, 1, 2); + init_data.add_ushort_triangle(2, 3, 0); - ::glVertex2f(1.0f, 1.0f); - ::glVertex2f(-1.0f, 1.0f); - glsafe(::glEnd()); + m_background.init_from(std::move(init_data)); + } + + GLShaderProgram* shader = wxGetApp().get_shader("background"); + if (shader != nullptr) { + shader->start_using(); + shader->set_uniform("top_color", use_error_color ? ERROR_BG_LIGHT_COLOR : DEFAULT_BG_LIGHT_COLOR); + shader->set_uniform("bottom_color", bottom_color); + + m_background.render(); + shader->stop_using(); + } glsafe(::glEnable(GL_DEPTH_TEST)); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 084293e54e..efae16d7ee 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -714,6 +714,7 @@ public: CameraTarget m_camera_target; #endif // ENABLE_SHOW_CAMERA_TARGET + GLModel m_background; public: explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed); ~GLCanvas3D(); @@ -1119,7 +1120,7 @@ private: void _picking_pass(); void _rectangular_selection_picking_pass(); - void _render_background() const; + void _render_background(); void _render_bed(bool bottom, bool show_axes); void _render_bed_for_picking(bool bottom); //BBS: add part plate related logic diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5585d2f7fb..c7bd5cdccc 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -35,6 +35,8 @@ std::pair GLShadersManager::init() // basic shader, used to render all what was previously rendered using the immediate mode valid &= append_shader("flat", { "flat.vs", "flat.fs" }); + // used to render 3D scene background + valid &= append_shader("background", { "background.vs", "background.fs" }); // used to render bed axes and model, selection hints, gcode sequential view marker model, preview shells, options in gcode preview valid &= append_shader("gouraud_light", { "gouraud_light.vs", "gouraud_light.fs" }); //used to render thumbnail