mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-03 08:12:07 +00:00
Compare commits
5 Commits
feature/up
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bf43d92b9 | ||
|
|
95b781745d | ||
|
|
80e64f80a6 | ||
|
|
477208a969 | ||
|
|
2e08b19d6b |
2
.github/workflows/update-translation.yml
vendored
2
.github/workflows/update-translation.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@v7
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#version 140
|
||||
// Multisample depth texture for the anti-aliased outline (see 3DScene.cpp render_with_outline).
|
||||
// Optional on the GLSL 140 path: if unavailable, fallback to a non-multisample depth texture.
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||
//BBS: add grey and orange
|
||||
@@ -36,7 +39,14 @@ uniform SlopeDetection slope;
|
||||
|
||||
//BBS: add outline_color
|
||||
uniform bool is_outline;
|
||||
// The outline is a per-fragment discard mask, which the framebuffer MSAA cannot smooth, so the
|
||||
// silhouette is resolved per sample from a multisample copy of the outlined model's depth buffer.
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
uniform sampler2DMS depth_tex;
|
||||
uniform int msaa_samples; // samples in depth_tex, 1 when MSAA is off
|
||||
#else
|
||||
uniform sampler2D depth_tex;
|
||||
#endif
|
||||
uniform vec2 screen_size;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
@@ -99,7 +109,22 @@ float GetTolerance(float d, float k)
|
||||
return -k*(d+A)*(d+A)/B;
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
// Depth of sample s at integer pixel coord.
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
float FetchDepth(ivec2 coord, int s)
|
||||
{
|
||||
// texelFetch has no wrap mode, so clamp to the edge texel (sampler2D used CLAMP_TO_EDGE).
|
||||
ivec2 sz = textureSize(depth_tex);
|
||||
return abs(texelFetch(depth_tex, clamp(coord, ivec2(0), sz - 1), s).r);
|
||||
}
|
||||
#else
|
||||
float FetchDepth(ivec2 coord, int s)
|
||||
{
|
||||
return abs(texture(depth_tex, (vec2(coord) + 0.5) / screen_size).r);
|
||||
}
|
||||
#endif
|
||||
|
||||
float DetectSilho(ivec2 coord, ivec2 dir, int s)
|
||||
{
|
||||
// -------------------------------------------
|
||||
// x0 ___ x1----o
|
||||
@@ -112,11 +137,10 @@ float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
// and expected (as if x0..3 where on the same
|
||||
// plane) depth values.
|
||||
// -------------------------------------------
|
||||
|
||||
float x0 = abs(texture(depth_tex, (fragCoord + dir*-2.0) / screen_size).r);
|
||||
float x1 = abs(texture(depth_tex, (fragCoord + dir*-1.0) / screen_size).r);
|
||||
float x2 = abs(texture(depth_tex, (fragCoord + dir* 0.0) / screen_size).r);
|
||||
float x3 = abs(texture(depth_tex, (fragCoord + dir* 1.0) / screen_size).r);
|
||||
float x0 = FetchDepth(coord + dir*-2, s);
|
||||
float x1 = FetchDepth(coord + dir*-1, s);
|
||||
float x2 = FetchDepth(coord, s);
|
||||
float x3 = FetchDepth(coord + dir* 1, s);
|
||||
|
||||
float d0 = (x1-x0);
|
||||
float d1 = (x2-x3);
|
||||
@@ -127,17 +151,45 @@ float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
float tol = GetTolerance(x2, 0.04);
|
||||
|
||||
return smoothstep(0.0, tol*tol, max( - r0*r1, 0.0));
|
||||
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
float DetectSilho(ivec2 coord, int s)
|
||||
{
|
||||
return max(
|
||||
DetectSilho(fragCoord, vec2(1,0)), // Horizontal
|
||||
DetectSilho(fragCoord, vec2(0,1)) // Vertical
|
||||
DetectSilho(coord, ivec2(1,0), s), // Horizontal
|
||||
DetectSilho(coord, ivec2(0,1), s) // Vertical
|
||||
);
|
||||
}
|
||||
|
||||
// Full response of one sample. Reduce the max() per sample and average only afterwards:
|
||||
// max(mean) <= mean(max), and averaging first hollows out diagonal and curved lines.
|
||||
float DetectSilhoSample(ivec2 coord, int s)
|
||||
{
|
||||
float v = DetectSilho(coord, s);
|
||||
// Makes silhouettes thicker.
|
||||
for (int i = 1; i <= INFLATE; ++i)
|
||||
{
|
||||
v = max(v, DetectSilho(coord + ivec2(i, 0), s));
|
||||
v = max(v, DetectSilho(coord + ivec2(0, i), s));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// Average the per-sample coverage into the sub-pixel anti-aliasing of the line.
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
{
|
||||
ivec2 coord = ivec2(fragCoord);
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
int n = max(msaa_samples, 1);
|
||||
#else
|
||||
const int n = 1;
|
||||
#endif
|
||||
float acc = 0.0;
|
||||
for (int s = 0; s < n; ++s)
|
||||
acc += DetectSilhoSample(coord, s);
|
||||
return acc / float(n);
|
||||
}
|
||||
|
||||
// Returns a lighting multiplier in [1 - shadow_intensity, 1]: < 1 where the fragment is
|
||||
// occluded from the light in the shadow map. 3x3 PCF softens the edges.
|
||||
float shadow_shade()
|
||||
@@ -224,14 +276,7 @@ void main()
|
||||
//BBS: add outline_color
|
||||
if (is_outline) {
|
||||
color = vec4((vec3(intensity.y) + color.rgb * intensity.x) * shade, color.a);
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
float s = DetectSilho(fragCoord);
|
||||
// Makes silhouettes thicker.
|
||||
for(int i=1;i<=INFLATE; i++)
|
||||
{
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0)));
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(0, i)));
|
||||
}
|
||||
float s = DetectSilho(gl_FragCoord.xy);
|
||||
if (s < 0.01)
|
||||
discard;
|
||||
out_color = vec4(mix(color.rgb, getBackfaceColor(color.rgb), s), color.a);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#version 140
|
||||
// Multisample depth texture for the anti-aliased outline (see 3DScene.cpp render_with_outline).
|
||||
// Optional on the GLSL 140 path: if unavailable, fallback to a non-multisample depth texture.
|
||||
#extension GL_ARB_texture_multisample : enable
|
||||
|
||||
const vec3 ZERO = vec3(0.0, 0.0, 0.0);
|
||||
const vec3 LightRed = vec3(0.78, 0.0, 0.0);
|
||||
@@ -51,7 +54,14 @@ uniform SlopeDetection slope;
|
||||
|
||||
//BBS: add outline_color
|
||||
uniform bool is_outline;
|
||||
// The outline is a per-fragment discard mask, which the framebuffer MSAA cannot smooth, so the
|
||||
// silhouette is resolved per sample from a multisample copy of the outlined model's depth buffer.
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
uniform sampler2DMS depth_tex;
|
||||
uniform int msaa_samples; // samples in depth_tex, 1 when MSAA is off
|
||||
#else
|
||||
uniform sampler2D depth_tex;
|
||||
#endif
|
||||
uniform vec2 screen_size;
|
||||
|
||||
#ifdef ENABLE_ENVIRONMENT_MAP
|
||||
@@ -100,12 +110,27 @@ float GetTolerance(float d, float k)
|
||||
return -k*(d+A)*(d+A)/B;
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
// Depth of sample s at integer pixel coord.
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
float FetchDepth(ivec2 coord, int s)
|
||||
{
|
||||
float x0 = abs(texture(depth_tex, (fragCoord + dir*-2.0) / screen_size).r);
|
||||
float x1 = abs(texture(depth_tex, (fragCoord + dir*-1.0) / screen_size).r);
|
||||
float x2 = abs(texture(depth_tex, (fragCoord + dir* 0.0) / screen_size).r);
|
||||
float x3 = abs(texture(depth_tex, (fragCoord + dir* 1.0) / screen_size).r);
|
||||
// texelFetch has no wrap mode, so clamp to the edge texel (sampler2D used CLAMP_TO_EDGE).
|
||||
ivec2 sz = textureSize(depth_tex);
|
||||
return abs(texelFetch(depth_tex, clamp(coord, ivec2(0), sz - 1), s).r);
|
||||
}
|
||||
#else
|
||||
float FetchDepth(ivec2 coord, int s)
|
||||
{
|
||||
return abs(texture(depth_tex, (vec2(coord) + 0.5) / screen_size).r);
|
||||
}
|
||||
#endif
|
||||
|
||||
float DetectSilho(ivec2 coord, ivec2 dir, int s)
|
||||
{
|
||||
float x0 = FetchDepth(coord + dir*-2, s);
|
||||
float x1 = FetchDepth(coord + dir*-1, s);
|
||||
float x2 = FetchDepth(coord, s);
|
||||
float x3 = FetchDepth(coord + dir* 1, s);
|
||||
|
||||
float d0 = (x1-x0);
|
||||
float d1 = (x2-x3);
|
||||
@@ -116,17 +141,45 @@ float DetectSilho(vec2 fragCoord, vec2 dir)
|
||||
float tol = GetTolerance(x2, 0.04);
|
||||
|
||||
return smoothstep(0.0, tol*tol, max( - r0*r1, 0.0));
|
||||
|
||||
}
|
||||
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
float DetectSilho(ivec2 coord, int s)
|
||||
{
|
||||
return max(
|
||||
DetectSilho(fragCoord, vec2(1,0)),
|
||||
DetectSilho(fragCoord, vec2(0,1))
|
||||
DetectSilho(coord, ivec2(1,0), s),
|
||||
DetectSilho(coord, ivec2(0,1), s)
|
||||
);
|
||||
}
|
||||
|
||||
// Full response of one sample. Reduce the max() per sample and average only afterwards:
|
||||
// max(mean) <= mean(max), and averaging first hollows out diagonal and curved lines.
|
||||
float DetectSilhoSample(ivec2 coord, int s)
|
||||
{
|
||||
float v = DetectSilho(coord, s);
|
||||
// Makes silhouettes thicker.
|
||||
for (int i = 1; i <= INFLATE; ++i)
|
||||
{
|
||||
v = max(v, DetectSilho(coord + ivec2(i, 0), s));
|
||||
v = max(v, DetectSilho(coord + ivec2(0, i), s));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// Average the per-sample coverage into the sub-pixel anti-aliasing of the line.
|
||||
float DetectSilho(vec2 fragCoord)
|
||||
{
|
||||
ivec2 coord = ivec2(fragCoord);
|
||||
#ifdef GL_ARB_texture_multisample
|
||||
int n = max(msaa_samples, 1);
|
||||
#else
|
||||
const int n = 1;
|
||||
#endif
|
||||
float acc = 0.0;
|
||||
for (int s = 0; s < n; ++s)
|
||||
acc += DetectSilhoSample(coord, s);
|
||||
return acc / float(n);
|
||||
}
|
||||
|
||||
float compute_ssao_factor(vec3 normal, vec3 view_dir, vec3 eye_pos)
|
||||
{
|
||||
vec3 normal_dx = dFdx(normal);
|
||||
@@ -270,13 +323,7 @@ void main()
|
||||
if (is_outline) {
|
||||
vec3 shaded_rgb = (vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS * shade;
|
||||
vec4 shaded_color = vec4(clamp(shaded_rgb, vec3(0.0), vec3(1.0)), color.a);
|
||||
vec2 fragCoord = gl_FragCoord.xy;
|
||||
float s = DetectSilho(fragCoord);
|
||||
for(int i=1;i<=INFLATE; i++)
|
||||
{
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0)));
|
||||
s = max(s, DetectSilho(fragCoord.xy + vec2(0, i)));
|
||||
}
|
||||
float s = DetectSilho(gl_FragCoord.xy);
|
||||
if (s < 0.01)
|
||||
discard;
|
||||
out_color = vec4(mix(shaded_color.rgb, getBackfaceColor(shaded_color.rgb), s), shaded_color.a);
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
min(p1), max(p1), defined(false) { merge(p2); merge(p3); }
|
||||
|
||||
template<class It, class = IteratorOnly<It>>
|
||||
BoundingBoxBase(It from, It to)
|
||||
BoundingBoxBase(It from, It to) : BoundingBoxBase()
|
||||
{ construct(*this, from, to); }
|
||||
|
||||
BoundingBoxBase(const PointsType &points)
|
||||
|
||||
@@ -1857,12 +1857,12 @@ static inline void base_support_extend_infill_lines(Polylines &infill, BoundaryI
|
||||
const bool first = graph.first(cp);
|
||||
int extend_next_idx = -1;
|
||||
int extend_prev_idx = -1;
|
||||
coord_t dist_y_prev;
|
||||
coord_t dist_y_next;
|
||||
double arc_len_prev;
|
||||
double arc_len_next;
|
||||
coord_t dist_y_prev = 0;
|
||||
coord_t dist_y_next = 0;
|
||||
double arc_len_prev = 0;
|
||||
double arc_len_next = 0;
|
||||
|
||||
if (! graph.next_vertical(cp)){
|
||||
if (! graph.next_vertical(cp)) {
|
||||
size_t i = cp.point_idx;
|
||||
size_t j = next_idx_modulo(i, contour);
|
||||
while (j != cp.next_on_contour->point_idx) {
|
||||
|
||||
@@ -184,7 +184,7 @@ struct LayerResult {
|
||||
// It is used for the pressure equalizer because it needs to buffer one layer back.
|
||||
bool nop_layer_result { false };
|
||||
|
||||
static LayerResult make_nop_layer_result() { return {"", std::numeric_limits<coord_t>::max(), false, false, true}; }
|
||||
static LayerResult make_nop_layer_result() { return {"", std::numeric_limits<size_t>::max(), false, false, true}; }
|
||||
};
|
||||
|
||||
class GCode {
|
||||
|
||||
@@ -70,6 +70,9 @@ float FullTransparentModdifiedToFixAlpha = 0.3f;
|
||||
// value like 0.18f could not because in C++ (int)(0.18f * 255) == 45 however in OpenGL it renders this as 46
|
||||
// which breaks the `SelectMachineDialog::record_edge_pixels_data()` function!
|
||||
float FULL_BLACK_THRESHOLD = 0.2f;
|
||||
// Keep depth_tex away from texture unit 0 to avoid sampler-type aliasing with
|
||||
// shadow/environment samplers when realistic view is disabled.
|
||||
static constexpr int OUTLINE_DEPTH_TEX_UNIT = 5;
|
||||
|
||||
Slic3r::ColorRGBA adjust_color_for_rendering(const Slic3r::ColorRGBA &colors)
|
||||
{
|
||||
@@ -518,6 +521,37 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
|
||||
glsafe(::glStencilMask(0xFF));
|
||||
glsafe(::glDisable(GL_STENCIL_TEST));
|
||||
// render the outline using depth buffer and discard the pixels that are not on the outline
|
||||
// The silhouette is resolved per sample in the shader (see DetectSilho in gouraud.fs/phong.fs).
|
||||
// That needs the GL 3.2 entry points and a shader that declares depth_tex as sampler2DMS, which
|
||||
// only the 140 ones do and only under GL_ARB_texture_multisample - so ask the compiled program
|
||||
// rather than the GL version, or a sampler2D ends up bound to a multisample texture.
|
||||
// Only the Arb branch below allocates a multisample texture, so keep the target consistent with it.
|
||||
const bool use_msaa_outline = framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb &&
|
||||
GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 2) &&
|
||||
shader->get_uniform_location("msaa_samples") >= 0;
|
||||
const GLenum depth_tex_target = use_msaa_outline ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
|
||||
// Keep the depth texture off image unit 0. The object shaders leave shadow_map (and
|
||||
// environment_tex) at the default sampler value 0 whenever the shadow pass is skipped - which is
|
||||
// the case with realistic view off - and GL forbids two sampler types referring to the same image
|
||||
// unit. A sampler2DMS on unit 0 then makes every draw fail with INVALID_OPERATION on drivers that
|
||||
// enforce it (Mesa), i.e. the model disappears entirely. Unit 5 is unused (shadow_map takes 4).
|
||||
const int depth_tex_unit = OUTLINE_DEPTH_TEX_UNIT;
|
||||
int aa_samples = 1;
|
||||
if (use_msaa_outline) {
|
||||
if (const AppConfig* app_config = GUI::wxGetApp().app_config; app_config != nullptr) {
|
||||
const std::string value = app_config->get(SETTING_OPENGL_AA_SAMPLES);
|
||||
if (value == "2" || value == "4" || value == "8" || value == "16")
|
||||
aa_samples = ::atoi(value.c_str());
|
||||
}
|
||||
// Never request more samples than the driver supports for depth textures (a 1-sample texture
|
||||
// is used when MSAA is disabled, keeping a single code path for the sampler2DMS shader).
|
||||
GLint max_samples = 1;
|
||||
glsafe(::glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &max_samples));
|
||||
if (aa_samples > max_samples)
|
||||
aa_samples = max_samples < 1 ? 1 : max_samples;
|
||||
if (aa_samples < 1)
|
||||
aa_samples = 1;
|
||||
}
|
||||
// 1st. render pass, render the model into a separate render target that has only depth buffer
|
||||
GLuint depth_fbo = 0;
|
||||
GLuint depth_tex = 0;
|
||||
@@ -525,21 +559,26 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
|
||||
glsafe(::glGenFramebuffers(1, &depth_fbo));
|
||||
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0 + depth_tex_unit));
|
||||
glsafe(::glGenTextures(1, &depth_tex));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
glsafe(::glBindTexture(depth_tex_target, depth_tex));
|
||||
if (use_msaa_outline) {
|
||||
// Multisample textures do not take filter/wrap parameters.
|
||||
glsafe(::glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, aa_samples, GL_DEPTH_COMPONENT32F, cnv_size.get_width(), cnv_size.get_height(), GL_TRUE));
|
||||
} else {
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, cnv_size.get_width(), cnv_size.get_height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr));
|
||||
}
|
||||
|
||||
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0));
|
||||
glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_tex_target, depth_tex, 0));
|
||||
} else {
|
||||
glsafe(::glGenFramebuffersEXT(1, &depth_fbo));
|
||||
glsafe(::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, depth_fbo));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0 + depth_tex_unit));
|
||||
glsafe(::glGenTextures(1, &depth_tex));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
@@ -550,12 +589,15 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
|
||||
|
||||
glsafe(::glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_tex, 0));
|
||||
}
|
||||
// Unbind before drawing: the texture is this framebuffer's depth attachment, so leaving it bound
|
||||
// to a sampled unit would be a feedback loop.
|
||||
glsafe(::glBindTexture(depth_tex_target, 0));
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0));
|
||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||
if (tverts_range == std::make_pair<size_t, size_t>(0, -1))
|
||||
model.render(shader);
|
||||
else
|
||||
model.render(this->tverts_range, shader);
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
// 2nd. render pass, just a normal render with the depth buffer passed as a texture
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb) {
|
||||
@@ -565,13 +607,17 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size)
|
||||
}
|
||||
shader->set_uniform("is_outline", true);
|
||||
shader->set_uniform("screen_size", Vec2f{cnv_size.get_width(), cnv_size.get_height()});
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, depth_tex));
|
||||
shader->set_uniform("depth_tex", 0);
|
||||
shader->set_uniform("msaa_samples", aa_samples);
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0 + depth_tex_unit));
|
||||
glsafe(::glBindTexture(depth_tex_target, depth_tex));
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0));
|
||||
shader->set_uniform("depth_tex", depth_tex_unit);
|
||||
simple_render(shader, model_objects, colors);
|
||||
|
||||
// Some clean up to do
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0 + depth_tex_unit));
|
||||
glsafe(::glBindTexture(depth_tex_target, 0));
|
||||
glsafe(::glActiveTexture(GL_TEXTURE0));
|
||||
shader->set_uniform("is_outline", false);
|
||||
if (framebuffers_type == GUI::OpenGLManager::EFramebufferType::Arb) {
|
||||
glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||
@@ -1075,6 +1121,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
||||
|
||||
const float support_normal_z = get_selection_support_normal_z();
|
||||
|
||||
// Prime depth_tex on every frame so non-outline draws do not keep the
|
||||
// default sampler unit 0, which can conflict with other sampler types.
|
||||
shader->set_uniform("depth_tex", OUTLINE_DEPTH_TEX_UNIT);
|
||||
|
||||
for (GLVolumeWithIdAndZ& volume : to_render) {
|
||||
#if ENABLE_MODIFIERS_ALWAYS_TRANSPARENT
|
||||
if (type == ERenderType::Transparent) {
|
||||
|
||||
@@ -548,7 +548,7 @@ void RemoveButtonBorder(wxWindow* win)
|
||||
GtkCssProvider* provider = gtk_css_provider_new();
|
||||
|
||||
const char* css =
|
||||
"button {"
|
||||
"button, button:hover, button:active, button:focus {"
|
||||
" border: none;"
|
||||
" outline: none;"
|
||||
" box-shadow: none;"
|
||||
@@ -589,6 +589,58 @@ void RemoveButtonBorder(wxWindow* win)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RemoveInputBorder(wxWindow* win)
|
||||
{
|
||||
GtkWidget* widget = win->GetHandle();
|
||||
if (!widget) return;
|
||||
|
||||
#if GTK_CHECK_VERSION(3, 0, 0)
|
||||
// GTK3+: use CSS provider
|
||||
GtkCssProvider* provider = gtk_css_provider_new();
|
||||
|
||||
// Target 'entry' and its inner subnodes (like text selection areas)
|
||||
const char* css =
|
||||
"entry, entry text, entry undershoot {"
|
||||
" border: none;"
|
||||
" outline: none;"
|
||||
" box-shadow: none;"
|
||||
" padding: 0px;"
|
||||
" margin: 0px;"
|
||||
" min-height: 0px;"
|
||||
" min-width: 0px;"
|
||||
" background: none;"
|
||||
"}";
|
||||
|
||||
#if GTK_CHECK_VERSION(4, 0, 0)
|
||||
// GTK4
|
||||
gtk_css_provider_load_from_data(provider, css, -1);
|
||||
#else
|
||||
// GTK3
|
||||
gtk_css_provider_load_from_data(provider, css, -1, nullptr);
|
||||
#endif
|
||||
|
||||
GtkStyleContext* ctx = gtk_widget_get_style_context(widget);
|
||||
gtk_style_context_add_provider(
|
||||
ctx,
|
||||
GTK_STYLE_PROVIDER(provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER
|
||||
);
|
||||
g_object_unref(provider);
|
||||
|
||||
#else
|
||||
// GTK2: Target the x/y thickness of the entry widget
|
||||
gtk_rc_parse_string(
|
||||
"style \"no-padding-entry\" {"
|
||||
" xthickness = 0"
|
||||
" ythickness = 0"
|
||||
" GtkEntry::inner-border = { 0, 0, 0, 0 }"
|
||||
" GtkEntry::focus-line-width = 0"
|
||||
"}"
|
||||
"class \"GtkEntry\" style \"no-padding-entry\""
|
||||
);
|
||||
#endif
|
||||
}
|
||||
#endif // __WXGTK__
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -472,8 +472,9 @@ void dataview_remove_insets(wxDataViewCtrl* dv);
|
||||
void staticbox_remove_margin(wxStaticBox* sb);
|
||||
#endif
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
void RemoveButtonBorder(wxWindow* win);
|
||||
#ifdef __WXGTK__
|
||||
void RemoveButtonBorder(wxWindow* win); // for wxButton/wxBitmapToggleButton based controls (SwitchButton, CheckBox)
|
||||
void RemoveInputBorder(wxWindow* win); // for TextCtrl based controls (TextInput, ComboBox, SpinInput..)
|
||||
#endif
|
||||
|
||||
#if defined(__WXOSX__) || defined(__linux__)
|
||||
|
||||
@@ -865,6 +865,9 @@ PlaterPresetComboBox::PlaterPresetComboBox(wxWindow *parent, Preset::Type preset
|
||||
clr_picker = new wxBitmapButton(parent, wxID_ANY, {}, wxDefaultPosition, wxSize(FromDIP(20), FromDIP(20)), wxBU_EXACTFIT | wxBU_AUTODRAW | wxBORDER_NONE);
|
||||
clr_picker->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE));
|
||||
clr_picker->SetToolTip(_L("Click to select filament color"));
|
||||
#ifdef __WXGTK__
|
||||
RemoveButtonBorder(clr_picker);
|
||||
#endif
|
||||
clr_picker->Bind(wxEVT_BUTTON, [this](wxCommandEvent& e) {
|
||||
// Check if it's an official filament
|
||||
auto fila_type = Preset::remove_suffix_modified(GetValue().ToUTF8().data());
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "../wxExtensions.hpp"
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
#ifdef __WXGTK__
|
||||
#include "../GUI_Utils.hpp"
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@ CheckBox::CheckBox(wxWindow *parent, int id)
|
||||
Bind(wxEVT_LEAVE_WINDOW, &CheckBox::updateBitmap, this);
|
||||
#endif
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveButtonBorder(this);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
#include "../wxExtensions.hpp"
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "../GUI_Utils.hpp"
|
||||
#endif
|
||||
|
||||
namespace Slic3r {
|
||||
namespace GUI {
|
||||
RadioBox::RadioBox(wxWindow *parent)
|
||||
@@ -15,6 +19,7 @@ RadioBox::RadioBox(wxWindow *parent)
|
||||
// Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); });
|
||||
update();
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveButtonBorder(this);
|
||||
wxSize bestSize = GetBestSize();
|
||||
bestSize.IncTo(m_on.GetBmpSize());
|
||||
SetSize(bestSize);
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "../GUI_Utils.hpp"
|
||||
#endif
|
||||
|
||||
BEGIN_EVENT_TABLE(SpinInput, StaticBox)
|
||||
|
||||
EVT_KEY_DOWN(SpinInput::keyPressed)
|
||||
@@ -58,6 +62,11 @@ void SpinInput::Create(wxWindow *parent,
|
||||
state_handler.attach({&label_color, &text_color});
|
||||
state_handler.update_binds();
|
||||
text_ctrl = new TextCtrl(this, wxID_ANY, text, {20, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER, wxTextValidator(wxFILTER_DIGITS));
|
||||
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveInputBorder(text_ctrl);
|
||||
#endif
|
||||
|
||||
text_ctrl->SetFont(Label::Body_14);
|
||||
text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
|
||||
text_ctrl->SetForegroundColour(text_color.colorForStates(state_handler.states()));
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "libslic3r/MacUtils.hpp"
|
||||
#endif
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
#ifdef __WXGTK__
|
||||
#include "../GUI_Utils.hpp"
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,7 @@ SwitchButton::SwitchButton(wxWindow* parent, wxWindowID id)
|
||||
Bind(wxEVT_TOGGLEBUTTON, [this](auto& e) { update(); e.Skip(); });
|
||||
SetFont(Label::Body_12);
|
||||
|
||||
#ifdef __WXGTK3__
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveButtonBorder(this);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/dcgraph.h>
|
||||
|
||||
#ifdef __WXGTK__
|
||||
#include "../GUI_Utils.hpp"
|
||||
#endif
|
||||
|
||||
BEGIN_EVENT_TABLE(TextInput, StaticBox)
|
||||
|
||||
EVT_PAINT(TextInput::paintEvent)
|
||||
@@ -60,6 +64,11 @@ void TextInput::Create(wxWindow * parent,
|
||||
state_handler.attach({&label_color, & text_color});
|
||||
state_handler.update_binds();
|
||||
text_ctrl = new TextCtrl(this, wxID_ANY, text, {4, 4}, wxDefaultSize, style | wxBORDER_NONE | wxTE_PROCESS_ENTER);
|
||||
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveInputBorder(text_ctrl);
|
||||
#endif
|
||||
|
||||
text_ctrl->SetFont(Label::Body_14);
|
||||
text_ctrl->SetInitialSize(text_ctrl->GetBestSize());
|
||||
text_ctrl->SetBackgroundColour(background_color.colorForStates(state_handler.states()));
|
||||
|
||||
@@ -1022,6 +1022,10 @@ ScalableButton::ScalableButton( wxWindow * parent,
|
||||
m_width = size.x * 10 / em;
|
||||
m_height= size.y * 10 / em;
|
||||
}
|
||||
|
||||
#ifdef __WXGTK__
|
||||
Slic3r::GUI::RemoveButtonBorder(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user