diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index 572b37c7f..2f2ca5fb5 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -64,6 +64,9 @@ void main() float world_normal_z_fs = world_normal_z; if (compute_triangle_normals_in_fs) { vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz))); +#ifdef FLIP_TRIANGLE_NORMALS + triangle_normal = -triangle_normal; +#endif // First transform the normal into camera space and normalize the result. eye_normal_fs = normalize(gl_NormalMatrix * triangle_normal); diff --git a/src/libslic3r/Platform.cpp b/src/libslic3r/Platform.cpp index ae02c42b3..4aa72c95f 100644 --- a/src/libslic3r/Platform.cpp +++ b/src/libslic3r/Platform.cpp @@ -3,6 +3,12 @@ #include #include +#if defined(__APPLE__) +#include +#include +#include +#endif + namespace Slic3r { static auto s_platform = Platform::Uninitialized; @@ -16,8 +22,39 @@ void detect_platform() s_platform_flavor = PlatformFlavor::Generic; #elif defined(__APPLE__) BOOST_LOG_TRIVIAL(info) << "Platform: OSX"; - s_platform = Platform::OSX; - s_platform_flavor = PlatformFlavor::Generic; + s_platform = Platform::OSX; + s_platform_flavor = PlatformFlavor::GenericOSX; + { + cpu_type_t type = 0; + size_t size = sizeof(type); + if (sysctlbyname("hw.cputype", &type, &size, NULL, 0) == 0) { + type &= ~CPU_ARCH_MASK; + if (type == CPU_TYPE_X86) { + int proc_translated = 0; + size = sizeof(proc_translated); + // Detect if native CPU is really X86 or PrusaSlicer runs through Rosetta. + if (sysctlbyname("sysctl.proc_translated", &proc_translated, &size, NULL, 0) == -1) { + if (errno == ENOENT) { + // Native CPU is X86, and property sysctl.proc_translated doesn't exist. + s_platform_flavor = PlatformFlavor::OSXOnX86; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86"; + } + } else if (proc_translated == 1) { + // Native CPU is ARM and PrusaSlicer runs through Rosetta. + s_platform_flavor = PlatformFlavor::OSXOnArm; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm"; + } else { + // Native CPU is X86. + s_platform_flavor = PlatformFlavor::OSXOnX86; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnX86"; + } + } else if (type == CPU_TYPE_ARM) { + // Native CPU is ARM + s_platform_flavor = PlatformFlavor::OSXOnArm; + BOOST_LOG_TRIVIAL(info) << "Platform flavor: OSXOnArm"; + } + } + } #elif defined(__linux__) BOOST_LOG_TRIVIAL(info) << "Platform: Linux"; s_platform = Platform::Linux; diff --git a/src/libslic3r/Platform.hpp b/src/libslic3r/Platform.hpp index 735728e89..1b4d74c02 100644 --- a/src/libslic3r/Platform.hpp +++ b/src/libslic3r/Platform.hpp @@ -28,6 +28,12 @@ enum class PlatformFlavor WSL2, // For Platform::BSDUnix OpenBSD, + // For Platform::OSX + GenericOSX, + // For Apple's on Intel X86 CPU + OSXOnX86, + // For Apple's on Arm CPU + OSXOnArm, }; // To be called on program start-up. diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5ee14c526..788fe90c0 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -1,4 +1,5 @@ #include "libslic3r/libslic3r.h" +#include "libslic3r/Platform.hpp" #include "GLShadersManager.hpp" #include "3DScene.hpp" #include "GUI_App.hpp" @@ -43,9 +44,19 @@ std::pair GLShadersManager::init() // used to render extrusion and travel paths as lines in gcode preview valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); // used to render objects in 3d editor - valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } + // For Apple's on Arm CPU computed triangle normals inside fragment shader using dFdx and dFdy has the opposite direction. + // Because of this, objects had darker colors inside the multi-material gizmo. + // Based on https://stackoverflow.com/a/66206648, the similar behavior was also spotted on some other devices with Arm CPU. + if (platform_flavor() == PlatformFlavor::OSXOnArm) + valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" }, { "FLIP_TRIANGLE_NORMALS"sv #if ENABLE_ENVIRONMENT_MAP - , { "ENABLE_ENVIRONMENT_MAP"sv } + , "ENABLE_ENVIRONMENT_MAP"sv +#endif + }); + else + valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } +#if ENABLE_ENVIRONMENT_MAP + , { "ENABLE_ENVIRONMENT_MAP"sv } #endif ); // used to render variable layers heights in 3d editor