diff --git a/.gitignore b/.gitignore
index e3a9db477..c4df3f3f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ local-lib
build-linux/*
deps/build-linux/*
**/.DS_Store
+/.idea/
diff --git a/resources/icons/toolbar_arrow_2.svg b/resources/icons/toolbar_arrow_2.svg
new file mode 100644
index 000000000..5ff1cfa2b
--- /dev/null
+++ b/resources/icons/toolbar_arrow_2.svg
@@ -0,0 +1,22 @@
+
+
+
\ No newline at end of file
diff --git a/resources/localization/ca/PrusaSlicer.mo b/resources/localization/ca/PrusaSlicer.mo
index 167cc324d..c5f940d31 100644
Binary files a/resources/localization/ca/PrusaSlicer.mo and b/resources/localization/ca/PrusaSlicer.mo differ
diff --git a/resources/localization/ca/PrusaSlicer_ca.po b/resources/localization/ca/PrusaSlicer_ca.po
index b4f99487b..39fe9b44b 100644
--- a/resources/localization/ca/PrusaSlicer_ca.po
+++ b/resources/localization/ca/PrusaSlicer_ca.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-09 09:04+0100\n"
-"PO-Revision-Date: 2021-12-16 18:50+0100\n"
+"PO-Revision-Date: 2022-03-04 17:01+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ca\n"
@@ -90,7 +90,7 @@ msgstr ""
#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:84
#, boost-format
msgid "PrusaSlicer has encountered a fatal error: \"%1%\""
-msgstr ""
+msgstr "PrusaSlicer ha trobat un error crític: \"%1%\""
#: src/slic3r/GUI/BackgroundSlicingProcess.cpp:85
msgid ""
@@ -1887,7 +1887,7 @@ msgstr "Imatge del firmware:"
#: src/slic3r/GUI/FirmwareDialog.cpp:813
msgid "Select a file"
-msgstr ""
+msgstr "Seleccioneu un fitxer"
#: src/slic3r/GUI/FirmwareDialog.cpp:815
#: src/slic3r/GUI/PhysicalPrinterDialog.cpp:297
@@ -3495,11 +3495,11 @@ msgstr "Preparant pestanyes de configuració"
#: src/slic3r/GUI/GUI_App.cpp:1334 src/slic3r/GUI/Preferences.cpp:287
msgid "Restore window position on start"
-msgstr ""
+msgstr "Restaura la posició de la finestra a l'inici"
#: src/slic3r/GUI/GUI_App.cpp:1336
msgid "PrusaSlicer started after a crash"
-msgstr ""
+msgstr "PrusaSlicer s'ha reiniciat després d'una fallada"
#: src/slic3r/GUI/GUI_App.cpp:1337
#, boost-format
@@ -3513,16 +3513,27 @@ msgid ""
"To avoid this problem, consider disabling \"%4%\" in \"Preferences\". "
"Otherwise, the application will most likely crash again next time."
msgstr ""
+"PrusaSlicer va crashejar la darrera vegada en intentar establir la posició "
+"de la finestra.\n"
+"Lamentem les molèsties, malauradament passa amb certes configuracions de "
+"monitor múltiple.\n"
+"El motiu més precís de l'accident: \"%1%\".\n"
+"Per obtenir més informació, consulteu el nostre rastrejador d'incidències de "
+"GitHub: \"%2%\" i \"%3%\"\n"
+"\n"
+"Per evitar aquest problema, considereu desactivar \"%4%\" a \"Preferències"
+"\". En cas contrari, és probable que l'aplicació es torni a crashejar la "
+"propera vegada."
#: src/slic3r/GUI/GUI_App.cpp:1349
#, boost-format
msgid "Disable \"%1%\""
-msgstr ""
+msgstr "Deshabilitar \"%1%\""
#: src/slic3r/GUI/GUI_App.cpp:1350
#, boost-format
msgid "Leave \"%1%\" enabled"
-msgstr ""
+msgstr "Deixa \"%1%\" habilitat"
#: src/slic3r/GUI/GUI_App.cpp:1677
msgid ""
@@ -3805,6 +3816,7 @@ msgstr "PrusaSlicer recordarà la vostra elecció."
#: src/slic3r/GUI/GUI_App.cpp:3101
msgid "You will not be asked about it again on hyperlinks hovering."
msgstr ""
+"No se us tornarà a preguntar al respecte quan passis per sobre de l'enllaç."
#: src/slic3r/GUI/GUI_App.cpp:3102 src/slic3r/GUI/Plater.cpp:1738
#, boost-format
@@ -5008,15 +5020,16 @@ msgstr "S'ha produït un error inesperat"
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:21
msgid "Best surface quality"
-msgstr ""
+msgstr "Màxima qualitat de superfície"
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:23
msgid "Optimize object rotation for best surface quality."
msgstr ""
+"Optimitzar la rotació de l'objecte per a la màxima qualitat de superfície."
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:24
msgid "Reduced overhang slopes"
-msgstr ""
+msgstr "Pendents de voladís reduïts"
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:26
msgid ""
@@ -5025,14 +5038,20 @@ msgid ""
"Note that this method will try to find the best surface of the object for "
"touching the print bed if no elevation is set."
msgstr ""
+"Optimitza la rotació d'objectes per tenir una quantitat mínima de voladissos "
+"que necessiten estructures de suport.\n"
+"Tingueu en compte que aquest mètode intentarà trobar la millor superfície de "
+"l'objecte per tocar el llit d'impressió si no s'estableix cap elevació."
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:30
msgid "Lowest Z height"
-msgstr ""
+msgstr "Mínima alçada Z"
#: src/slic3r/GUI/Jobs/RotoptimizeJob.hpp:32
msgid "Rotate the model to have the lowest z height for faster print time."
msgstr ""
+"Rota el model per tenir l'alçada z més baixa i un temps d'impressió més "
+"ràpid."
#: src/slic3r/GUI/Jobs/RotoptimizeJob.cpp:59
msgid "Searching for optimal orientation"
@@ -6985,7 +7004,7 @@ msgstr "Voleu desar els canvis a \"%1%\"?"
#: src/slic3r/GUI/Plater.cpp:1732 src/slic3r/GUI/Preferences.cpp:222
msgid "Ask for unsaved changes in project"
-msgstr ""
+msgstr "Preguntar pels canvis no desats al projecte"
#: src/slic3r/GUI/Plater.cpp:1735
msgid ""
@@ -6993,6 +7012,9 @@ msgid ""
"- Closing PrusaSlicer,\n"
"- Loading or creating a new project"
msgstr ""
+"No et preguntarà pels canvis no guardats la propera vegada que: \n"
+"- Tanquis PrusaSlicer,\n"
+"- Carreguis o creis un nou projecte"
#: src/slic3r/GUI/Plater.cpp:2197
#, c-format, boost-format
@@ -7622,6 +7644,9 @@ msgid ""
"- Closing PrusaSlicer,\n"
"- Loading or creating a new project"
msgstr ""
+"Sol·licita sempre canvis no desats en el projecte, quan: \n"
+"- Tancament PrusaSlicer,\n"
+"- Càrrega o creació d'un nou projecte"
#: src/slic3r/GUI/Preferences.cpp:233
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:897
@@ -7629,6 +7654,8 @@ msgid ""
"Ask to save unsaved changes in presets when closing the application or when "
"loading a new project"
msgstr ""
+"Demana desar els canvis no desats en els predefinits en tancar l'aplicació o "
+"en carregar un projecte nou"
#: src/slic3r/GUI/Preferences.cpp:235
msgid ""
@@ -7636,6 +7663,9 @@ msgid ""
"- Closing PrusaSlicer while some presets are modified,\n"
"- Loading a new project while some presets are modified"
msgstr ""
+"Preguntar sempre pels canvis no guardats en els predefinits, quan:\n"
+"- En tancar PrusaSlicer mentre es modifiquen alguns ajustaments,\n"
+"- En carregar un nou projecte mentre es modifiquen alguns ajustaments"
#: src/slic3r/GUI/Preferences.cpp:242
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:896
@@ -7647,15 +7677,20 @@ msgid ""
"Always ask for unsaved changes in presets when selecting new preset or "
"resetting a preset"
msgstr ""
+"Preguntar sempre pels canvis no guardats en predefinits en seleccionar un "
+"nou ajustament o en restablir un ajustament"
#: src/slic3r/GUI/Preferences.cpp:249
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:895
msgid "Ask for unsaved changes in presets when creating new project"
msgstr ""
+"Preguntar pels canvis no desats en predefinits en crear un nou projecte"
#: src/slic3r/GUI/Preferences.cpp:251
msgid "Always ask for unsaved changes in presets when creating new project"
msgstr ""
+"Preguntar sempre pels canvis no guardats en predefinits en crear un nou "
+"projecte"
#: src/slic3r/GUI/Preferences.cpp:258
msgid "Associate .gcode files to PrusaSlicer G-code Viewer"
@@ -7688,6 +7723,7 @@ msgstr "Mostra la pantalla de presentació"
#: src/slic3r/GUI/Preferences.cpp:289
msgid "If enabled, PrusaSlicer will be open at the position it was closed"
msgstr ""
+"Si està habilitat, PrusaSlicer s'obrirà en la posició en què s'ha tancat"
#: src/slic3r/GUI/Preferences.cpp:295
msgid "Clear Undo / Redo stack on new project"
@@ -7779,7 +7815,7 @@ msgstr ""
#: src/slic3r/GUI/Preferences.cpp:384
msgid "If enabled, PrusaSlicer will not open hyperlinks in your browser."
-msgstr ""
+msgstr "Si està habilitat, PrusaSlicer no obrirà hipervincles al navegador."
#: src/slic3r/GUI/Preferences.cpp:391
msgid "Use colors for axes values in Manipulation panel"
@@ -9224,19 +9260,19 @@ msgstr "Ajust"
#: src/slic3r/GUI/Tab.cpp:3938
msgid "Find"
-msgstr "Cerca"
+msgstr "Cercar"
#: src/slic3r/GUI/Tab.cpp:3939
msgid "Replace with"
-msgstr ""
+msgstr "Substitueix-ho per"
#: src/slic3r/GUI/Tab.cpp:4028
msgid "Regular expression"
-msgstr ""
+msgstr "Expressió normal"
#: src/slic3r/GUI/Tab.cpp:4032
msgid "Case insensitive"
-msgstr ""
+msgstr "No distingeix minúscules/majúscules"
#: src/slic3r/GUI/Tab.cpp:4036
msgid "Whole word"
@@ -9244,11 +9280,11 @@ msgstr "Paraula sencera"
#: src/slic3r/GUI/Tab.cpp:4040
msgid "Match single line"
-msgstr ""
+msgstr "Coincideix amb una sola línia"
#: src/slic3r/GUI/Tab.cpp:4143
msgid "Are you sure you want to delete all substitutions?"
-msgstr ""
+msgstr "Esteu segur que voleu suprimir totes les substitucions?"
#: src/slic3r/GUI/Tab.cpp:4275
msgid ""
@@ -9512,12 +9548,16 @@ msgid ""
"You will not be asked about the unsaved changes in presets the next time you "
"create new project"
msgstr ""
+"No et preguntarà pels canvis no guardats en predefinits la propera vegada "
+"que creis un nou projecte"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:899
msgid ""
"You will not be asked about the unsaved changes in presets the next time you "
"switch a preset"
msgstr ""
+"No et preguntarà pels canvis no guardats en predefinits la propera vegada "
+"que canvíis d'ajust"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:900
msgid ""
@@ -9526,6 +9566,10 @@ msgid ""
"- Closing PrusaSlicer while some presets are modified,\n"
"- Loading a new project while some presets are modified"
msgstr ""
+"Preguntar sempre pels canvis no guardats en predefinits la propera vegada "
+"que::\n"
+"- Tanquis PrusaSlicer mentre es modifiquen alguns ajustaments,\n"
+"- Carreguis un nou projecte mentre es modifiquen alguns ajustaments"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:903
msgid "PrusaSlicer will remember your action."
@@ -9617,7 +9661,7 @@ msgstr "Comptador d'extrusors"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1454
msgid "Select presets to compare"
-msgstr ""
+msgstr "Seleccioneu els predefinits per comparar"
#: src/slic3r/GUI/UnsavedChangesDialog.cpp:1503
msgid "Show all presets (including incompatible)"
@@ -10245,24 +10289,26 @@ msgstr ""
#: src/slic3r/Config/Snapshot.cpp:584
msgid "Taking a configuration snapshot failed."
-msgstr ""
+msgstr "No s'ha pogut prendre una instantània de configuració."
#: src/slic3r/Config/Snapshot.cpp:598
msgid ""
"PrusaSlicer has encountered an error while taking a configuration snapshot."
msgstr ""
+"El PrusaSlicer ha trobat un error mentre feia una instantània de "
+"configuració."
#: src/slic3r/Config/Snapshot.cpp:599
msgid "PrusaSlicer error"
-msgstr ""
+msgstr "Error de PrusaSlicer"
#: src/slic3r/Config/Snapshot.cpp:601
msgid "Continue"
-msgstr ""
+msgstr "Continuar"
#: src/slic3r/Config/Snapshot.cpp:601
msgid "Abort"
-msgstr ""
+msgstr "Avortar"
#: src/libslic3r/GCode.cpp:539
msgid "There is an object with no extrusions in the first layer."
@@ -10313,7 +10359,7 @@ msgstr ""
#: src/libslic3r/GCode.cpp:1236 src/libslic3r/GCode.cpp:1247
msgid "No extrusions were generated for objects."
-msgstr ""
+msgstr "No s'han generat extrusions per als objectes."
#: src/libslic3r/GCode.cpp:1445
msgid ""
@@ -10706,18 +10752,25 @@ msgid ""
"each layer to prevent loss of floating point accuracy. Add \"G92 E0\" to "
"layer_gcode."
msgstr ""
+"L'adreçament relatiu de l'extrusor requereix restablir la posició de "
+"l'extrusor a cada capa per evitar la pèrdua de precisió de coma flotant. "
+"Afegiu \"G92 E0\" a layer_gcode."
#: src/libslic3r/Print.cpp:665
msgid ""
"\"G92 E0\" was found in before_layer_gcode, which is incompatible with "
"absolute extruder addressing."
msgstr ""
+"\"G92 E0\" s'ha trobat a before_layer_gcode, el qual és incompatible amb "
+"l'adreçament absolut d'extrusor."
#: src/libslic3r/Print.cpp:667
msgid ""
"\"G92 E0\" was found in layer_gcode, which is incompatible with absolute "
"extruder addressing."
msgstr ""
+"\"G92 E0\" s'ha trobat a layer_gcode, el qual és incompatible amb "
+"l'adreçament absolut d'extrusor."
#: src/libslic3r/Print.cpp:809
msgid "Infilling layers"
@@ -12309,11 +12362,11 @@ msgstr ""
#: src/libslic3r/PrintConfig.cpp:1361
msgid "G-code substitutions"
-msgstr ""
+msgstr "Substitucions de codi G"
#: src/libslic3r/PrintConfig.cpp:1362
msgid "Find / replace patterns in G-code lines and substitute them."
-msgstr ""
+msgstr "Cerca / substitueix patrons en línies de codi G i els substitueix."
#: src/libslic3r/PrintConfig.cpp:1367
msgid "High extruder current on filament swap"
@@ -15587,7 +15640,7 @@ msgid ""
"theVariable layer height tool. (Not available for SLA printers.)"
msgstr ""
"Alçada de capa variable\n"
-"Sabies que pot imprimir diferents regions del teu model amb una alçada de "
+"Sabies que pots imprimir diferents regions del teu model amb una alçada de "
"capa diferent i suavitzar les transicions entre elles? Proveu "
"l'einaAlçada de capa variable. (No disponible per a impressores SLA.)"
@@ -15624,7 +15677,7 @@ msgid ""
"threshold area. (Expert mode only.)"
msgstr ""
"Àrea llindar de farciment sòlid\n"
-"Sabies que pot fer que les parts del seu model amb una secció transversal "
+"Sabies que pots fer que les parts del teu model amb una secció transversal "
"petita s'emplenin amb farciment sòlid automàticament? Ajusta elÀrea "
"llindar de farciment sòlid. (Només en mode Expert.)"
@@ -15837,13 +15890,44 @@ msgstr ""
"Sabies que pots posar el PrusaSlicer en mode de pantalla completa? Utilitzeu "
"la tecla d'accés ràpid F11."
-#: ../src/common/debugrpt.cpp:586
-msgid ""
-"\n"
-"Please send this report to the program maintainer, thank you!\n"
-msgstr ""
-"\n"
-"Envieu aquest informe al mantenidor del programa. Gràcies!\n"
+#~ msgid ""
+#~ "If enabled, the descriptions of configuration parameters in settings tabs "
+#~ "wouldn't work as hyperlinks. If disabled, the descriptions of "
+#~ "configuration parameters in settings tabs will work as hyperlinks."
+#~ msgstr ""
+#~ "Si està habilitat, les descripcions dels paràmetres de configuració a les "
+#~ "pestanyes de configuració no funcionaran com a hiperenllaços. Si està "
+#~ "deshabilitat, les descripcions dels paràmetres de configuració a les "
+#~ "pestanyes de configuració funcionaran com a hiperenllaços."
+
+#, c-format, boost-format
+#~ msgid ""
+#~ "PrusaSlicer detected another configuration folder at %s.\n"
+#~ "Its version is %s.\n"
+#~ "Last version you used in current configuration folder is %s.\n"
+#~ "Please note that PrusaSlicer uses different folders to save configuration "
+#~ "of alpha, beta and full release versions.\n"
+#~ "Would you like to copy found configuration to your current configuration "
+#~ "folder?\n"
+#~ "\n"
+#~ "If you select yes, PrusaSlicer will copy all profiles and other files "
+#~ "from found folder to the current one. Overwriting any existing file with "
+#~ "matching name.\n"
+#~ "If you select no, you will continue with current configuration."
+#~ msgstr ""
+#~ "PrusaSlicer ha detectat una altra carpeta de configuració a %s.\n"
+#~ "La vostra versió és %s.\n"
+#~ "La darrera versió que heu utilitzat a la carpeta de configuració actual "
+#~ "és %s.\n"
+#~ "Si us plau, tingueu en compte que PrusaSlicer utilitza diferents carpetes "
+#~ "per desar la configuració de les versions alfa, beta i final.\n"
+#~ "Voleu copiar la configuració trobada a la vostra carpeta de configuració "
+#~ "actual?\n"
+#~ "\n"
+#~ "Si seleccioneu sí, PrusaSlicer copiarà tots els perfils i altres fitxers "
+#~ "de la carpeta trobada a l'actual, sobreescrivint qualsevol fitxer "
+#~ "existent amb el mateix nom.\n"
+#~ "Si seleccioneu no, continuareu amb la configuració actual."
#: ../src/richtext/richtextstyledlg.cpp:210
#: ../src/richtext/richtextstyledlg.cpp:222
diff --git a/resources/profiles/Anycubic.idx b/resources/profiles/Anycubic.idx
index 12652625c..47bdd8c27 100644
--- a/resources/profiles/Anycubic.idx
+++ b/resources/profiles/Anycubic.idx
@@ -1,3 +1,5 @@
+min_slic3r_version = 2.4.1-rc1
+0.1.0 Added Anycubic 4Max Pro 2.0
min_slic3r_version = 2.3.2-alpha0
0.0.12 Updated Anycubic i3 MEGA(S) profiles.
0.0.11 Added bed model and texture for i3 Mega, i3 Mega S.
diff --git a/resources/profiles/Anycubic.ini b/resources/profiles/Anycubic.ini
index 821d87462..fd73c063e 100644
--- a/resources/profiles/Anycubic.ini
+++ b/resources/profiles/Anycubic.ini
@@ -5,7 +5,7 @@
name = Anycubic
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
-config_version = 0.0.12
+config_version = 0.1.0
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/Anycubic/
# changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@@ -57,6 +57,15 @@ family = MEGA
bed_model = i3megas_bed.stl
bed_texture = i3megas.svg
+[printer_model:4MAXPRO20]
+name = Anycubic 4Max Pro 2.0
+variants = 0.4
+technology = FFF
+family = 4Max
+bed_model = 4MAXPRO20_bed.stl
+bed_texture = 4MAXPRO20_texture.svg
+default_materials = Generic PLA @4Max Pro 2.0; Generic TPU @4Max Pro 2.0; Generic ABS @4Max Pro 2.0
+
[printer_model:PREDATOR]
name = Anycubic Predator
variants = 0.4; 0.6; 0.8
@@ -1902,17 +1911,339 @@ min_layer_height = 0.16
max_layer_height = 0.48
default_print_profile = 0.24mm 0.8 nozzle DETAILED QUALITY @PREDATOR
-#########################################
-########## end printer presets ##########
-#########################################
+## Anycubic 4MAX Pro 2.0
+## based on https://hartrusion.com/en/prusaslicer-config-for-anycubic-4max-pro-2-0/
+
+[print:*common_4max*]
+avoid_crossing_perimeters = 0
+avoid_crossing_perimeters_max_detour = 0
+bottom_fill_pattern = monotonic
+bottom_solid_layers = 4
+bridge_acceleration = 300
+bridge_angle = 0
+bridge_flow_ratio = 0.65
+bridge_speed = 30
+brim_separation = 0
+brim_type = outer_only
+brim_width = 0
+clip_multipart_objects = 1
+compatible_printers_condition = printer_model=="4MAXPRO20" and nozzle_diameter[0]==0.4
+complete_objects = 0
+default_acceleration = 900
+dont_support_bridges = 1
+draft_shield = disabled
+elefant_foot_compensation = 0.2
+ensure_vertical_shell_thickness = 1
+external_perimeter_extrusion_width = 0
+external_perimeter_speed = 35
+external_perimeters_first = 0
+extra_perimeters = 0
+extruder_clearance_height = 20
+extruder_clearance_radius = 20
+extrusion_width = 0.45
+fill_angle = 45
+fill_density = 20%
+fill_pattern = gyroid
+first_layer_acceleration = 300
+first_layer_acceleration_over_raft = 0
+first_layer_extrusion_width = 0.65
+first_layer_height = 0.3
+first_layer_speed = 20
+first_layer_speed_over_raft = 30
+fuzzy_skin = none
+fuzzy_skin_point_dist = 0.8
+fuzzy_skin_thickness = 0.3
+gap_fill_enabled = 1
+gap_fill_speed = 40
+gcode_comments = 0
+gcode_label_objects = 0
+gcode_resolution = 0.0125
+infill_acceleration = 600
+infill_anchor = 400%
+infill_anchor_max = 50
+infill_every_layers = 1
+infill_extruder = 1
+infill_extrusion_width = 0
+infill_first = 0
+infill_only_where_needed = 0
+infill_overlap = 23%
+infill_speed = 45
+inherits =
+interface_shells = 0
+ironing = 0
+ironing_flowrate = 15%
+ironing_spacing = 0.1
+ironing_speed = 15
+ironing_type = top
+layer_height = 0.2
+max_print_speed = 50
+max_volumetric_speed = 0
+min_skirt_length = 0
+only_retract_when_crossing_perimeters = 0
+ooze_prevention = 0
+output_filename_format = {input_filename_base}_{layer_height}mm_{filament_type[0]}_{print_time}.gcode
+overhangs = 1
+perimeter_acceleration = 500
+perimeter_extruder = 1
+perimeter_extrusion_width = 0
+perimeter_speed = 45
+perimeters = 3
+post_process =
+print_settings_id =
+raft_contact_distance = 0.1
+raft_expansion = 1.5
+raft_first_layer_density = 90%
+raft_first_layer_expansion = 3
+raft_layers = 0
+resolution = 0
+seam_position = aligned
+single_extruder_multi_material_priming = 1
+skirt_distance = 5
+skirt_height = 1
+skirts = 2
+slicing_mode = regular
+small_perimeter_speed = 20
+solid_infill_below_area = 0
+solid_infill_every_layers = 0
+solid_infill_extruder = 1
+solid_infill_extrusion_width = 0
+solid_infill_speed = 45
+spiral_vase = 0
+standby_temperature_delta = -5
+support_material = 0
+support_material_angle = 0
+support_material_auto = 1
+support_material_bottom_contact_distance = 0
+support_material_bottom_interface_layers = -1
+support_material_buildplate_only = 1
+support_material_closing_radius = 2
+support_material_contact_distance = 0.2
+support_material_enforce_layers = 0
+support_material_extruder = 1
+support_material_extrusion_width = 0.4
+support_material_interface_contact_loops = 0
+support_material_interface_extruder = 1
+support_material_interface_layers = 2
+support_material_interface_pattern = rectilinear
+support_material_interface_spacing = 0.2
+support_material_interface_speed = 30
+support_material_pattern = rectilinear-grid
+support_material_spacing = 2.5
+support_material_speed = 45
+support_material_style = grid
+support_material_synchronize_layers = 0
+support_material_threshold = 45
+support_material_with_sheath = 1
+support_material_xy_spacing = 60%
+thick_bridges = 1
+thin_walls = 0
+top_fill_pattern = monotonic
+top_infill_extrusion_width = 0.4
+top_solid_infill_speed = 30
+top_solid_layers = 5
+travel_speed = 60
+travel_speed_z = 0
+wipe_tower = 0
+wipe_tower_bridging = 10
+wipe_tower_brim_width = 2
+wipe_tower_no_sparse_layers = 0
+wipe_tower_rotation_angle = 0
+wipe_tower_width = 60
+wipe_tower_x = 180
+wipe_tower_y = 140
+xy_size_compensation = 0
+
+[print:0.15mm Detail @4Max Pro 2.0]
+inherits = *common_4max*
+layer_height = 0.15
+bottom_solid_layers = 5
+top_solid_layers = 7
+perimeter_speed = 40
+external_perimeter_speed = 25
+
+[print:0.20mm Quality @4Max Pro 2.0]
+inherits = *common_4max*
+external_perimeter_speed = 25
+
+[print:0.30mm Draft @4Max Pro 2.0]
+inherits = *common_4max*
+layer_height = 0.3
+bottom_solid_layers = 3
+top_solid_layers = 3
+
+[filament:*common_4max*]
+bed_temperature = 60
+bridge_fan_speed = 100
+compatible_printers_condition = printer_model=="4MAXPRO20"
+cooling = 1
+disable_fan_first_layers = 1
+extrusion_multiplier = 1
+fan_always_on = 1
+fan_below_layer_time = 30
+filament_density = 1.24
+filament_diameter = 1.75
+filament_max_volumetric_speed = 0
+filament_type = PLA
+first_layer_bed_temperature = 60
+first_layer_temperature = 210
+full_fan_speed_layer = 5
+max_fan_speed = 100
+min_fan_speed = 80
+min_print_speed = 10
+slowdown_below_layer_time = 15
+temperature = 205
+
+[filament:*PLA_4max*]
+inherits = *common_4max*
+
+[filament:Generic PLA @4Max Pro 2.0]
+inherits = *PLA_4max*
+filament_vendor = Generic
+
+[filament:Anycubic PLA @4Max Pro 2.0]
+inherits = *PLA_4max*
+first_layer_temperature = 215
+temperature = 207
+filament_vendor = Anycubic
+
+[filament:Generic ABS @4Max Pro 2.0]
+filament_vendor = Generic
+compatible_printers_condition = printer_model=="4MAXPRO20"
+bed_temperature = 100
+first_layer_bed_temperature = 100
+temperature = 245
+first_layer_temperature = 245
+bridge_fan_speed = 15
+cooling = 1
+disable_fan_first_layers = 3
+extrusion_multiplier = 1
+fan_always_on = 0
+fan_below_layer_time = 60
+filament_colour = #800000
+filament_density = 1.04
+filament_diameter = 1.75
+filament_type = ABS
+full_fan_speed_layer = 0
+max_fan_speed = 0
+min_fan_speed = 0
+min_print_speed = 10
+slowdown_below_layer_time = 25
+
+[filament:Generic TPU @4Max Pro 2.0]
+filament_vendor = Generic
+bed_temperature = 60
+bridge_fan_speed = 0
+compatible_printers_condition = printer_model=="4MAXPRO20"
+cooling = 1
+disable_fan_first_layers = 3
+extrusion_multiplier = 1
+fan_always_on = 0
+fan_below_layer_time = 60
+filament_colour = #211AB5
+filament_density = 1.19
+filament_deretract_speed = 20
+filament_diameter = 1.75
+filament_retract_speed = 30
+filament_type = FLEX
+filament_max_volumetric_speed = 1.65
+first_layer_bed_temperature = 60
+first_layer_temperature = 215
+full_fan_speed_layer = 0
+max_fan_speed = 0
+min_fan_speed = 0
+min_print_speed = 10
+slowdown_below_layer_time = 20
+temperature = 215
+
+[filament:Polymaker PolyFlex TPU95 @4Max Pro 2.0]
+filament_vendor = Polymaker
+bed_temperature = 45
+bridge_fan_speed = 80
+compatible_printers_condition = printer_model=="4MAXPRO20"
+cooling = 1
+disable_fan_first_layers = 5
+extrusion_multiplier = 1.04
+fan_always_on = 1
+fan_below_layer_time = 45
+filament_colour = #FD7D2F
+filament_density = 1.22
+filament_deretract_speed = 25
+filament_diameter = 1.75
+filament_max_volumetric_speed = 1.65
+filament_retract_length = 4
+filament_retract_restart_extra = 0.1
+filament_retract_speed = 60
+filament_type = FLEX
+first_layer_bed_temperature = 55
+first_layer_temperature = 215
+full_fan_speed_layer = 8
+max_fan_speed = 50
+min_fan_speed = 25
+min_print_speed = 10
+slowdown_below_layer_time = 10
+temperature = 217
+
+[printer:Anycubic 4Max Pro 2.0]
+printer_model = 4MAXPRO20
+printer_variant = 0.4
+printer_technology = FFF
+bed_shape = 0x0,270x0,270x210,0x210
+color_change_gcode = M600
+default_filament_profile = Generic PLA @4Max Pro 2.0
+default_print_profile = 0.20mm Quality @4Max Pro 2.0
+deretract_speed = 25
+end_gcode = M104 S0 ; turn off extruder heating\nM140 S0 ; turn off bed heating\nM107 ; turn off fans\nG91 ; relative positioning\nG0 Z+0.5 ; move Z up a tiny bit\nG90 ; absolute positioning\nG0 X135 Y105 F{machine_max_feedrate_x[0]*60} ; move extruder to center position\nG0 Z190.5 F{machine_max_feedrate_z[0]*60} ; lower the plattform to Z min\nM84 ; steppers off\nG90 ; absolute positioning\n
+extruder_offset = 0x0
+gcode_flavor = marlin
+machine_limits_usage = time_estimate_only
+machine_max_acceleration_e = 5000
+machine_max_acceleration_extruding = 1250
+machine_max_acceleration_retracting = 1250
+machine_max_acceleration_travel = 1500
+machine_max_acceleration_x = 900
+machine_max_acceleration_y = 900
+machine_max_acceleration_z = 100
+machine_max_feedrate_e = 120
+machine_max_feedrate_x = 200
+machine_max_feedrate_y = 200
+machine_max_feedrate_z = 16
+machine_max_jerk_e = 5
+machine_max_jerk_x = 6
+machine_max_jerk_y = 6
+machine_max_jerk_z = 0.2
+machine_min_extruding_rate = 0
+machine_min_travel_rate = 0
+max_layer_height = 0.3
+max_print_height = 190
+min_layer_height = 0.07
+nozzle_diameter = 0.4
+pause_print_gcode = M601
+remaining_times = 0
+retract_before_travel = 2
+retract_before_wipe = 0%
+retract_layer_change = 1
+retract_length = 2.5
+retract_length_toolchange = 10
+retract_lift = 0
+retract_lift_above = 0
+retract_lift_below = 0
+retract_restart_extra = 0
+retract_restart_extra_toolchange = 0
+retract_speed = 35
+silent_mode = 0
+single_extruder_multi_material = 0
+start_gcode = G21 ; metric values\nG90 ; absolute positioning\nM82 ; set extruder to absolute mode\nM140 S[first_layer_bed_temperature] ; set bed temp\nG28 X0 Y0 ; home X and Y\nG28 Z0 ; home Z\nG1 Z30 F{machine_max_feedrate_z[0]*60} ; move Z a bit down to not blow on the bed edge while heating\nG1 X10 F3900 ; let some space on x to prevent the filament cooling exhaust from beeing blocked by the servo motor\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM104 S[first_layer_temperature] ; set extruder temp\nM106 S80 ; turn on fan to prevent air nozzle melt while heating up\nM109 S[first_layer_temperature] ; wait for extruder temp\nM107 ; start with the fan off\nG28 X0 ; goto X home again\nG92 E0 ; zero the extruded length\nG1 Z0.2 F360 ; move plattform upwards\n; extrude material next to the plattform (comment or remove following lines to disable)\nG1 F180 E20 ; extrude some material next to the plattform\nG92 E0 ; zero the extruded length\nG1 E-[retract_length] F{retract_speed[0]*60} ; do a filament retract\nG92 E0 ; zero the extruded length again\nG1 X5 F3900 ; move sideways to get rid of that string\nG1 E[retract_length] F{retract_speed[0]*60} ; do a filament deretract with retract parameters\nG92 E0 ; zero the extruded length again\n; draw intro line (comment or remove following lines to disable)\nG1 X30 E5 F700 ; draw intro line\nG92 E0 ; zero the extruded length\nG1 E-[retract_length] F{retract_speed[0]*60} ; do a filament retract\nG1 X40 Z2.0 ; move away from the introline\nG92 E0 ; zero the extruded length again\nG1 E[retract_length] F{retract_speed[0]*60} ; do a filament deretract with retract parameters\n; end of intro line code\nM117 Printing...\nG5
+use_firmware_retraction = 0
+use_relative_e_distances = 0
+use_volumetric_e = 0
+variable_layer_height = 1
+wipe = 0
+z_offset = 0
-#########################################
########## SLA printer presets ##########
-#########################################
-
[sla_print:*common print ANYCUBIC SLA*]
-compatible_printers_condition = family=="PHOTON MONO"
+compatible_printers_condition = printer_notes=~/.*PHOTONMONOX.*/
layer_height = 0.05
output_filename_format = [input_filename_base].pwmx
pad_edge_radius = 0.5
diff --git a/resources/profiles/Anycubic/4MAXPRO20_bed.stl b/resources/profiles/Anycubic/4MAXPRO20_bed.stl
new file mode 100644
index 000000000..2b3534fa9
Binary files /dev/null and b/resources/profiles/Anycubic/4MAXPRO20_bed.stl differ
diff --git a/resources/profiles/Anycubic/4MAXPRO20_texture.svg b/resources/profiles/Anycubic/4MAXPRO20_texture.svg
new file mode 100644
index 000000000..edea26d50
--- /dev/null
+++ b/resources/profiles/Anycubic/4MAXPRO20_texture.svg
@@ -0,0 +1,259 @@
+
+
diff --git a/resources/profiles/Anycubic/4MAXPRO20_thumbnail.png b/resources/profiles/Anycubic/4MAXPRO20_thumbnail.png
new file mode 100644
index 000000000..2c9679483
Binary files /dev/null and b/resources/profiles/Anycubic/4MAXPRO20_thumbnail.png differ
diff --git a/resources/profiles/Creality/ENDER3PRO_thumbnail.png b/resources/profiles/Creality/ENDER3PRO_thumbnail.png
new file mode 100644
index 000000000..68ed43b7f
Binary files /dev/null and b/resources/profiles/Creality/ENDER3PRO_thumbnail.png differ
diff --git a/resources/profiles/PrusaResearch.idx b/resources/profiles/PrusaResearch.idx
index f90ba8279..9ee903563 100644
--- a/resources/profiles/PrusaResearch.idx
+++ b/resources/profiles/PrusaResearch.idx
@@ -1,4 +1,5 @@
min_slic3r_version = 2.4.0-rc
+1.4.3 Added new filament profiles and SLA materials.
1.4.2 Added SLA material profiles.
1.4.1 Updated firmware version.
1.4.0 Updated for the PrusaSlicer 2.4.0-rc release. Updated SLA material colors.
diff --git a/resources/profiles/PrusaResearch.ini b/resources/profiles/PrusaResearch.ini
index 71a86dde8..3182eba6b 100644
--- a/resources/profiles/PrusaResearch.ini
+++ b/resources/profiles/PrusaResearch.ini
@@ -5,7 +5,7 @@
name = Prusa Research
# Configuration version of this file. Config file will only be installed, if the config_version differs.
# This means, the server may force the PrusaSlicer configuration to be downgraded.
-config_version = 1.4.2
+config_version = 1.4.3
# Where to get the updates from?
config_update_url = https://files.prusa3d.com/wp-content/uploads/repository/PrusaSlicer-settings-master/live/PrusaResearch/
changelog_url = https://files.prusa3d.com/?latest=slicer-profiles&lng=%1%
@@ -477,7 +477,7 @@ perimeter_acceleration = 800
perimeter_speed = 50
solid_infill_speed = 50
top_infill_extrusion_width = 0.4
-top_solid_layers = 7
+top_solid_layers = 8
bridge_flow_ratio = 1
bridge_speed = 25
@@ -1543,6 +1543,7 @@ filament_max_volumetric_speed = 13
[filament:*ABSMINI*]
# inherits = *ABS*
bed_temperature = 100
+first_layer_bed_temperature = 100
filament_retract_length = 2.7
filament_retract_speed = nil
filament_deretract_speed = nil
@@ -2914,6 +2915,7 @@ inherits = *PET*
filament_vendor = BASF
filament_cost =
filament_density = 1.33
+filament_colour = #F7F7F7
first_layer_temperature = 220
first_layer_bed_temperature = 70
temperature = 215
@@ -2925,7 +2927,7 @@ bridge_fan_speed = 100
filament_type = PET
disable_fan_first_layers = 1
full_fan_speed_layer = 3
-filament_notes = "BASF Forward AM Ultrafuse PET\nMaterial profile version 1.0\n\nMaterial Description\nUltrafuse PET is made from a premium PET and prints as easy as PLA, but is much stronger. The filament has a large operating window for printing (temperature vs. speed), so it can be used on every 3D-printer. PET will give you outstanding printing results: a good layer adhesion, a high resolution and it is easy to handle. Ultrafuse PET can be 100% recycled, is watertight and has great colors and finish.\n\nPrinting Recommendations:\nUltrafuse PET can be printed directly onto a clean build plate. For challenging prints, use 3dLac to improve adhesion.\n"
+filament_notes = "Material Description\nUltrafuse PET is made from a premium PET and prints as easy as PLA, but is much stronger. The filament has a large operating window for printing (temperature vs. speed), so it can be used on every 3D-printer. PET will give you outstanding printing results: a good layer adhesion, a high resolution and it is easy to handle. Ultrafuse PET can be 100% recycled, is watertight and has great colors and finish.\n\nPrinting Recommendations:\nUltrafuse PET can be printed directly onto a clean build plate. For challenging prints, use 3dLac to improve adhesion."
filament_retract_length = 2
filament_retract_speed = 40
filament_retract_before_travel = 2
@@ -2943,7 +2945,7 @@ filament_cost =
filament_density = 1.25
filament_spool_weight = 0
filament_colour = #FFFFFF
-filament_notes = "BASF Forward AM Ultrafuse PLA PRO1\nMaterial profile version 1.0\n\nMaterial Description\nPLA PRO1 is an extremely versatile tough PLA filament made for professionals. It reduces your printing time by 30% – 80%, (subject to printer and object limitations) and the strength exceeds overall mechanical properties of printed ABS parts. Printer settings can be tuned to achieve blazing fast speeds or an unrivaled surface finish. The excellent quality control ensures the highest levels of consistency between colors and batches, it will perform as expected, every time.\n\nPrinting Recommendations:\nUltrafuse PLA PRO1 can be printed directly onto a clean build plate.\n"
+filament_notes = "Material Description\nPLA PRO1 is an extremely versatile tough PLA filament made for professionals. It reduces your printing time by 30% – 80%, (subject to printer and object limitations) and the strength exceeds overall mechanical properties of printed ABS parts. Printer settings can be tuned to achieve blazing fast speeds or an unrivaled surface finish. The excellent quality control ensures the highest levels of consistency between colors and batches, it will perform as expected, every time.\n\nPrinting Recommendations:\nUltrafuse PLA PRO1 can be printed directly onto a clean build plate."
filament_retract_length = 2
filament_retract_lift = 0
filament_retract_speed = 40
@@ -2969,15 +2971,303 @@ max_fan_speed = 20
bed_temperature = 100
disable_fan_first_layers = 3
filament_colour = #FFFFFF
-filament_notes = "BASF Forward AM Ultrafuse ABS\nMaterial profile version 1.0\n\nMaterial Description\nABS is the second most used 3D printing material. It is strong, flexible and has a high heat resistance. ABS is a preferred plastic for engineers and professional applications. ABS can be smoothened with acetone. To make a proper 3D print with ABS you will need a heated print bed. The filament is available in 9 colors.\n\nPrinting Recommendations:\n\nApply Tape, adhesion spray or glue to a clean build plate to improve adhesion.\n"
-filament_retract_length = 2
-filament_retract_speed = 40
+filament_notes = "Material Description\nABS is the second most used 3D printing material. It is strong, flexible and has a high heat resistance. ABS is a preferred plastic for engineers and professional applications. ABS can be smoothened with acetone. To make a proper 3D print with ABS you will need a heated print bed. The filament is available in 9 colors.\n\nPrinting Recommendations:\n\nApply Tape, adhesion spray or glue to a clean build plate to improve adhesion."
filament_retract_before_travel = 2
filament_wipe = 0
filament_retract_layer_change = 0
[filament:Ultrafuse ABS @MINI]
inherits = Ultrafuse ABS; *ABSMINI*
+filament_retract_layer_change = nil
+
+[filament:Ultrafuse ABS Fusion+]
+inherits = Ultrafuse ABS
+filament_density = 1.08
+first_layer_bed_temperature = 105
+temperature = 250
+filament_colour = #FFF8D9
+filament_notes = "Material Description\nABS Fusion+ made with Polyscope XILOY™ 3D is an engineering filament which has been optimized for 3D-printing. This special grade has been developed in collaboration with Polyscope Polymers - renowned for its material solutions in the automotive industry. ABS is a thermoplastic which is used in many applications. Although ABS has been classified as a standard material in 3D-printing it is known to be quite challenging to process. ABS Fusion+ combines the properties of ABS with an improved processability. The filament is based on an ABS grade which can be directly printed on glass without any adhesives or tape and has a higher success rate of prints due to extreme low warping."
+filament_retract_before_travel = 2
+filament_wipe = nil
+filament_retract_layer_change = 0
+filament_retract_lift = 0
+
+[filament:Ultrafuse ABS Fusion+ @MINI]
+inherits = Ultrafuse ABS Fusion+; *ABSMINI*
+first_layer_bed_temperature = 100
+filament_retract_layer_change = nil
+
+[filament:Ultrafuse ASA]
+inherits = Ultrafuse ABS Fusion+
+filament_density = 1.07
+filament_colour = #FFF4CA
+first_layer_temperature = 275
+temperature = 275
+first_layer_bed_temperature = 110
+bed_temperature = 105
+filament_type = ASA
+min_fan_speed = 25
+max_fan_speed = 50
+bridge_fan_speed = 100
+disable_fan_first_layers = 4
+filament_max_volumetric_speed = 5
+filament_notes = "Material Description\nUltrafuse ASA is a high-performance thermoplastic with similar mechanical properties as ABS. ASA offers additional benefits such as high outdoor weather resistance. The UV resistance, toughness, and rigidity make it an ideal material to 3D-print outdoor fixtures and appliances without losing its properties or color. When also taking into account the high heat resistance and high chemical resistance, this filament is a good choice for many types of applications.\n\nPrinting Recommendations:\nApply Magigoo PC, 3D lac or Dimafix to a clean build plate to improve adhesion."
+
+[filament:Ultrafuse ASA @MINI]
+inherits = Ultrafuse ASA; *ABSMINI*
+filament_type = ASA
+
+[filament:Ultrafuse HIPS]
+inherits = Ultrafuse ABS
+temperature = 250
+filament_density = 1.02
+filament_type = HIPS
+min_fan_speed = 20
+max_fan_speed = 20
+filament_soluble = 1
+filament_notes = "Material Description\nUltrafuse HIPS is a high-quality engineering thermoplastic, which is well known in the 3D-printing industry as a support material for ABS. But this material has additional properties to offer like good impact resistance, good dimensional stability, and easy post-processing. HiPS is a great material to use as a support for ABS because there is a good compatibility between the two materials, and HIPS is an easy breakaway support. Now you have the opportunity to create ABS models with complex geometry. HIPS is easy to post process with glue or with sanding paper."
+
+[filament:Ultrafuse HIPS @MINI]
+inherits = Ultrafuse HIPS; *ABSMINI*
+filament_type = HIPS
+min_fan_speed = 20
+max_fan_speed = 20
+
+[filament:Ultrafuse PA]
+inherits = Fillamentum Nylon FX256
+filament_vendor = BASF
+filament_density = 1.12
+filament_colour = #ECFAFF
+first_layer_temperature = 240
+temperature = 240
+first_layer_bed_temperature = 80
+bed_temperature = 70
+min_fan_speed = 0
+max_fan_speed = 0
+bridge_fan_speed = 0
+fan_below_layer_time = 30
+slowdown_below_layer_time = 20
+min_print_speed = 15
+filament_max_volumetric_speed = 11
+filament_retract_length = 1
+filament_retract_lift = 0
+filament_retract_before_travel = 2
+filament_retract_layer_change = 0
+filament_cost = 0
+filament_spool_weight = 0
+compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.02{else}0.04{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K12{elsif nozzle_diameter[0]==0.8};{else}M900 K20{endif} ; Filament gcode LA 1.0"
+filament_notes = "Material Description\nThe key features of Ultrafuse PA are the high strength and high modulus. Furthermore, Ultrafuse PA shows a good thermal distortion stability.\n\nPrinting Recommendations:\nApply PVA glue, Kapton tape or PA adhesive to a clean buildplate to improve adhesion."
+
+[filament:Ultrafuse PA6 GF30]
+inherits = Ultrafuse PA
+filament_density = 1.17
+first_layer_temperature = 270
+temperature = 270
+first_layer_bed_temperature = 100
+bed_temperature = 100
+filament_colour = #404040
+fan_always_on = 1
+min_fan_speed = 0
+max_fan_speed = 50
+bridge_fan_speed = 100
+disable_fan_first_layers = 1
+full_fan_speed_layer = 3
+slowdown_below_layer_time = 15
+filament_max_volumetric_speed = 10
+filament_retract_length = 1.2
+filament_retract_speed = 40
+filament_deretract_speed = 30
+filament_retract_lift = nil
+filament_wipe = 0
+filament_notes = "Material Description\nUltrafuse® PA6 GF30 is a unique compound specifically developed for FFF printing. Due to the glass fiber content of 30%, parts tend to warp less. In addition the excellent layer adhesion and its compatibility with the water soluble support Ultrafuse® BVOH make this material the perfect solution to develop industrial applications on an FFF printer.\n\nWith its high wear and chemical resistance, high stiffness and strength, Ultrafuse® PA6 GF30 is perfect for a wide variety of applications in automotive, electronics or transportation.\n\nUltrafuse PA6 GF30 is designed for functional prototyping and demanding applications such as industrial tooling, transportation, electronics, small appliances, sports & leisure\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened or Ruby nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nUltrafuse PA6 GF30 can be printed directly onto a clean build plate. For challenging prints, use Magigoo PA gluestick to improve adhesion."
+compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+
+[filament:Ultrafuse PAHT-CF15]
+inherits = Ultrafuse PA6 GF30
+filament_density = 1.23
+filament_notes = "Material Description\nPAHT CF15 is a high-performance 3D printing filament that opens new application fields in FFF printing. In parallel to its advanced mechanical properties, dimensional stability, and chemical resistance, it has very good processability. It works in any FFF printer with a hardened nozzle. In addition to that, it is compatible with water-soluble support material and HiPS, which allow printing complex geometries that work in challenging environments. PAHT CF15 has high heat resistance up to 130 °C and low moisture absorption.\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened or Ruby nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nUltrafuse PAHT-CF can be printed directly onto a clean build plate. For challenging prints, use 3dLac to improve adhesion."
+
+[filament:Ultrafuse PC-ABS-FR]
+inherits = Ultrafuse ABS
+filament_colour = #505050
+filament_density = 1.17
+first_layer_temperature = 275
+temperature = 275
+first_layer_bed_temperature = 110
+bed_temperature = 105
+filament_type = PC
+filament_max_volumetric_speed = 8
+filament_wipe = nil
+min_fan_speed = 20
+max_fan_speed = 20
+bridge_fan_speed = 30
+disable_fan_first_layers = 4
+compatible_printers_condition = printer_model!="MINI" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+filament_notes = "Material Description\nUltrafuse® PC/ABS FR Black is a V-0 flame retardant blend of Polycarbonate and ABS – two of the most used thermoplastics for engineering & electrical applications. The combination of these two materials results in a premium material with a mix of the excellent mechanical properties of PC and the comparably low printing temperature of ABS. Combined with a halogen free flame retardant, parts printed with Ultrafuse® PC/ABS FR Black feature great tensile and impact strength, higher thermal resistance than ABS and can fulfill the requirements of the UL94 V-0 standard.\n\nPrinting Recommendations:\nApply Magigoo PC to a clean build plate to improve adhesion."
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.02{elsif nozzle_diameter[0]==0.6}0.04{else}0.07{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K24{elsif nozzle_diameter[0]==0.8};{else}M900 K45{endif} ; Filament gcode LA 1.0"
+
+[filament:Ultrafuse PET-CF15]
+inherits = Ultrafuse PET
+filament_density = 1.36
+filament_colour = #404040
+first_layer_temperature = 270
+temperature = 270
+first_layer_bed_temperature = 75
+bed_temperature = 75
+min_fan_speed = 60
+max_fan_speed = 100
+bridge_fan_speed = 100
+disable_fan_first_layers = 1
+full_fan_speed_layer = 3
+slowdown_below_layer_time = 15
+fan_below_layer_time = 30
+filament_max_volumetric_speed = 10
+filament_retract_length = 1.2
+filament_retract_speed = 40
+filament_deretract_speed = 30
+filament_retract_lift = nil
+filament_wipe = 0
+start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.6}0.12{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/ and nozzle_diameter[0]==0.8}0.06{elsif printer_notes=~/.*PRINTER_MODEL_MINI.*/}0.2{elsif nozzle_diameter[0]==0.8}0.01{elsif nozzle_diameter[0]==0.6}0.04{else}0.05{endif} ; Filament gcode LA 1.5\n{if printer_notes=~/.*PRINTER_MODEL_MINI.*/};{elsif printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}M900 K200{elsif nozzle_diameter[0]==0.6}M900 K18{elsif nozzle_diameter[0]==0.8};{else}M900 K30{endif} ; Filament gcode LA 1.0"
+filament_notes = "Material Description\nPET CF15 is a Carbon Fiber reinforced PET which has precisely tuned material properties, for a wide range of technical applications. The filament is very strong and stiff and has high heat resistance. With its high dimensional stability and low abrasiveness, the filament offers an easy to print experience which allows direct printing on glass or a PEI sheet. It is compatible with HiPS for breakaway support and water soluble support and has an excellent surface finish.\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened or Ruby nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nUltrafuse PET-CF15 can be printed directly onto a clean build plate. For challenging prints, use 3dLac to improve adhesion."
+compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+
+[filament:Ultrafuse PLA]
+inherits = *PLA*
+filament_vendor = BASF
+filament_density = 1.25
+full_fan_speed_layer = 3
+filament_notes = "Material Description\nPLA is one of the most used materials for 3D printing. Ultrafuse PLA is available in a wide range of colors. The glossy feel often attracts those who print display models or items for household use. Many appreciate the plant-based origin of this material. When properly cooled, PLA has a high maximum printing speed and sharp printed corners. Combining this with low warping of the print makes it a popular plastic for home printers, hobbyists, prototyping and schools.\n\nPrinting Recommendations:\nUltrafuse PLA can be printed directly onto a clean build plate."
+
+[filament:Ultrafuse PP]
+inherits = Ultrafuse ABS
+filament_density = 0.91
+filament_colour = #F0F0F0
+first_layer_temperature = 240
+temperature = 240
+first_layer_bed_temperature = 80
+bed_temperature = 70
+min_fan_speed = 100
+max_fan_speed = 100
+bridge_fan_speed = 100
+disable_fan_first_layers = 1
+full_fan_speed_layer = 3
+fan_below_layer_time = 60
+slowdown_below_layer_time = 20
+min_print_speed = 10
+filament_type = PP
+filament_max_volumetric_speed = 2.5
+filament_retract_speed = 25
+filament_deretract_speed = 25
+filament_retract_layer_change = 0
+filament_wipe = nil
+filament_notes = "Material Description\nUltrafuse PP is high-performance thermoplastic with low density, high elasticity and high resistance to fatigue. The mechanical properties make it an ideal material for 3D-printing applications which have to endure high stress or strain. The filament has high chemical resistance and a high isolation value. PP is one of the most used materials in the world, due to its versatility and ability to engineer lightweight tough parts.\n\nPrinting Recommendations:\nApply PP tape or Magigoo PP adhesive to the buildplate for optimal adhesion."
+compatible_printers_condition = printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+
+[filament:Ultrafuse PP-GF30]
+inherits = Ultrafuse PP
+filament_density = 1.07
+filament_colour = #404040
+first_layer_temperature = 260
+temperature = 250
+first_layer_bed_temperature = 90
+bed_temperature = 40
+min_fan_speed = 40
+max_fan_speed = 75
+fan_always_on = 1
+fan_below_layer_time = 30
+slowdown_below_layer_time = 15
+min_print_speed = 15
+filament_retract_length = 1.2
+filament_retract_speed = 40
+filament_deretract_speed = 30
+filament_retract_lift = nil
+filament_wipe = 0
+filament_notes = "Ultrafuse PP GF30 is polypropylene, reinforced with 30% glass fiber content. The fibers in this compound are specially designed for 3D-printing filaments and are compatible with a wide range of standard FFF 3D-printers. The extreme stiffness makes this material highly suitable for demanding applications. Other key properties of PPGF30 are high heat resistance and improved UV-resistance. All these excellent properties make this filament highly suitable in an industrial environment.\n\nPrinting Recommendations:\nThis material contains fibers that have an abrasive effect on printer components. Use a hardened or Ruby nozzle with a diameter of 0.6 or larger for optimal performance and avoid damage to the nozzle.\n\nApply PP strapping tape or PPGF adhesive to a clean build plate for optimal adhesion."
+compatible_printers_condition = nozzle_diameter[0]>=0.6 and printer_model!="MINI" and printer_model!="MK2SMM" and ! (printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK(2.5|3).*/ and single_extruder_multi_material)
+
+[filament:Ultrafuse TPC-45D]
+inherits = *FLEX*
+filament_vendor = BASF
+extrusion_multiplier = 1
+filament_density = 1.15
+filament_colour = #0035EC
+first_layer_temperature = 235
+temperature = 235
+first_layer_bed_temperature = 60
+bed_temperature = 60
+min_fan_speed = 10
+max_fan_speed = 50
+bridge_fan_speed = 80
+fan_below_layer_time = 30
+slowdown_below_layer_time = 15
+min_print_speed = 15
+fan_always_on = 1
+cooling = 1
+filament_max_volumetric_speed = 1.2
+filament_retract_length = 1.2
+filament_retract_speed = 25
+filament_deretract_speed = 25
+filament_retract_lift = 0
+filament_wipe = nil
+filament_retract_before_wipe = nil
+filament_retract_before_travel = 2
+filament_retract_layer_change = 0
+filament_notes = "Material Description\nTPC 45D is a flexible, shore 45D, rubber-like Thermoplastic Copolyester Elastomer (TPE-C), which is derived from rapeseed oil and combines the best properties of elastomers (rubbers) and polyesters. The material delivers excellent adhesion in the Z-direction, meaning that the printed layers do not detach - even with extreme deformation.\n\nPrinting Recommendations:\nApply Magigoo Flex to a clean build plate to improve adhesion."
+
+## [filament:Ultrafuse TPS-90A]
+## inherits = Ultrafuse TPC-45D
+## filament_density = 1.04
+## extrusion_multiplier = 1.02
+## filament_colour = #FFFFFF
+## first_layer_temperature = 270
+## temperature = 265
+## first_layer_bed_temperature = 30
+## bed_temperature = 30
+## min_fan_speed = 20
+## max_fan_speed = 75
+## filament_notes = "Material Description\nUltrafuse® TPS 90A is an elastomer based on the raw material SEBS. The combination of durable and flexible building blocks leads to a very versatile material. Compared to other flexible 3D printing materials it shows more rubber-like soft touch haptics and better non-slip properties. Furthermore, the material shows a reduced moisture uptake, which allows for printing without pre-drying. Parts printed with Ultrafuse® TPS 90A show almost no visible layers or warpage, which makes it an excellent material choice for end-use parts. Producing multi-material parts is possible by printing it together with ABS.\n\nPrinting Recommendations:\nApply Tape, adhesion spray or glue to a clean build plate to improve adhesion."
+
+[filament:Ultrafuse TPU-64D]
+inherits = Ultrafuse TPC-45D
+filament_density = 1.16
+first_layer_temperature = 230
+temperature = 225
+first_layer_bed_temperature = 40
+bed_temperature = 40
+min_fan_speed = 20
+max_fan_speed = 100
+filament_notes = "Material Description\nUltrafuse® TPU 64D is the hardest elastomer in BASF Forward AM’s flexible productline. The material shows a relatively high rigidity while maintaining a certain flexibility. This filament is the perfect match for industrial applications requiring rigid parts being resistant to impact, wear and tear. Due to its property profile, the material can be used as an alternative for parts made from ABS and rubbers. Ultrafuse® TPU 64D is easy to print on direct drive and bowden style printers and is compatible with soluble BVOH support to realize the most complex geometries.\n\nPrinting Recommendations:\nUltrafuse TPU can be printed directly onto a clean build plate. A small amount of 3Dlac can make removal easier after printing."
+
+[filament:Ultrafuse TPU-85A]
+inherits = Ultrafuse TPU-64D
+filament_density = 1.11
+first_layer_temperature = 225
+temperature = 220
+filament_notes = "Material Description\nUltrafuse® TPU 85A comes in its natural white color. Chemical properties (e.g. resistance against particular substances) and tolerance for solvents can be made available, if these factors are relevant for a specific application. Generally, these properties correspond to publicly available data on polyether based TPUs. This material is not FDA conform. Good flexibility at low temperature, good wear performance and good damping behavior are the key features of Ultrafuse® TPU 85A.\n\nPrinting Recommendations:\nUltrafuse TPU can be printed directly onto a clean build plate. A small amount of 3Dlac can make removal easier after printing."
+
+[filament:Ultrafuse TPU-95A]
+inherits = Ultrafuse TPU-85A
+filament_density = 1.14
+first_layer_temperature = 230
+temperature = 225
+filament_notes = "Material Description\nUltrafuse® TPU 95A comes with a well-balanced profile of flexibility and durability. On top of that, it allows for easier and faster printing then softer TPU grades. Parts printed with Ultrafuse® TPU 95A show a high elongation, good impact resistance, excellent layer adhesion and a good resistance to oils and common industrially used chemicals. Due to its good printing behavior, Ultrafuse® TPU 95A is a good choice for starting printing flexible materials on both direct drive and bowden style printers.\n\nPrinting Recommendations:\nUltrafuse TPU can be printed directly onto a clean build plate. A small amount of 3Dlac can make removal easier after printing."
+
+[filament:Ultrafuse rPET]
+inherits = Ultrafuse PET
+filament_density = 1.27
+filament_colour = #9DC5FF
+first_layer_temperature = 235
+temperature = 235
+first_layer_bed_temperature = 80
+bed_temperature = 75
+min_fan_speed = 50
+max_fan_speed = 100
+fan_below_layer_time = 15
+filament_notes = "Material Description\nPET is mainly known by the well-known PET bottle material. This recycled has a natural transparent blueish look. It has excellent 3D printing properties and good mechanical characteristics."
+filament_retract_length = 1.2
+filament_retract_lift = 0.6
+filament_wipe = nil
[filament:Ultrafuse Metal]
inherits = *ABSC*
@@ -4629,7 +4919,7 @@ material_colour = #FF8040
inherits = *common 0.025*
exposure_time = 12
initial_exposure_time = 30
-material_type = Tough
+material_type = Casting
material_vendor = 3DM
material_colour = #B0B000
@@ -5084,6 +5374,38 @@ material_type = Tough
material_vendor = Ameralabs
material_colour = #C0C0C0
+[sla_material:PrimaCreator Tough Light Grey @0.025]
+inherits = *common 0.025*
+exposure_time = 6
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #C0C0C0
+
+[sla_material:PrimaCreator Tough Clear @0.025]
+inherits = *common 0.025*
+exposure_time = 5
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
+[sla_material:PrimaCreator Tough White @0.025]
+inherits = *common 0.025*
+exposure_time = 5
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #FFFFFF
+
+[sla_material:PrimaCreator Flex Clear @0.025]
+inherits = *common 0.025*
+exposure_time = 4.5
+initial_exposure_time = 30
+material_type = Flexible
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
[sla_material:Siraya Tech Simple Clear @0.025]
inherits = *common 0.025*
exposure_time = 8
@@ -5371,7 +5693,7 @@ inherits = *common 0.05*
exposure_time = 12
initial_exposure_time = 45
material_type = Tough
-material_vendor = Monocure
+material_vendor = 3DM
material_colour = #EC0000
[sla_material:Esun Bio-Photopolymer Resin White @0.05]
@@ -5550,6 +5872,38 @@ material_type = Tough
material_vendor = Photocentric
material_colour = #C0C0C0
+[sla_material:PrimaCreator Tough Light Grey @0.05]
+inherits = *common 0.05*
+exposure_time = 8.5
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #C0C0C0
+
+[sla_material:PrimaCreator Tough Clear @0.05]
+inherits = *common 0.05*
+exposure_time = 7
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
+[sla_material:PrimaCreator Tough White @0.05]
+inherits = *common 0.05*
+exposure_time = 7.5
+initial_exposure_time = 35
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #FFFFFF
+
+[sla_material:PrimaCreator Flex Clear @0.05]
+inherits = *common 0.05*
+exposure_time = 6.5
+initial_exposure_time = 30
+material_type = Flexible
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
[sla_material:Siraya Tech Simple Clear @0.05]
inherits = *common 0.05*
exposure_time = 10
@@ -6270,6 +6624,38 @@ material_type = Tough
material_vendor = Made for Prusa
material_colour = #FF8040
+[sla_material:PrimaCreator Tough Light Grey @0.1]
+inherits = *common 0.1*
+exposure_time = 14
+initial_exposure_time = 45
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #C0C0C0
+
+[sla_material:PrimaCreator Tough Clear @0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
+[sla_material:PrimaCreator Tough White @0.1]
+inherits = *common 0.1*
+exposure_time = 13
+initial_exposure_time = 45
+material_type = Tough
+material_vendor = PrimaCreator
+material_colour = #FFFFFF
+
+[sla_material:PrimaCreator Flex Clear @0.1]
+inherits = *common 0.1*
+exposure_time = 12
+initial_exposure_time = 35
+material_type = Flexible
+material_vendor = PrimaCreator
+material_colour = #F8F8F8
+
## SL1S materials ##
## 0.025 SL1S
@@ -6916,6 +7302,310 @@ material_type = Tough
material_vendor = Peopoly
material_colour = #F8F8F8
+[sla_material:3DM-ABS @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.6
+initial_exposure_time = 25
+material_type = Tough
+material_vendor = 3DM
+material_colour = #FF8040
+
+[sla_material:3DM-DENT @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.3
+initial_exposure_time = 36
+material_type = Dental
+material_vendor = 3DM
+material_colour = #FFEEE6
+
+[sla_material:3DM-HR Green @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = 3DM
+material_colour = #00B900
+
+[sla_material:3DM-HR Red Wine @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 6
+initial_exposure_time = 32
+material_type = Tough
+material_vendor = 3DM
+material_colour = #EC0000
+
+[sla_material:3DM-Vulcan Gold @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5
+initial_exposure_time = 24
+material_type = Casting
+material_vendor = 3DM
+material_colour = #B0B000
+
+[sla_material:3DM-XPRO White @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = 3DM
+material_colour = #FFFFFF
+
+[sla_material:Asiga Denta Model @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5
+initial_exposure_time = 24
+material_type = Dental
+material_vendor = Asiga
+material_colour = #FFEEE6
+
+[sla_material:Asiga PlasGRAY @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 9.7
+initial_exposure_time = 48
+material_type = Tough
+material_vendor = Asiga
+material_colour = #C0C0C0
+
+[sla_material:BlueCast EcoGray @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = BlueCast
+material_colour = #808080
+
+[sla_material:BlueCast Phrozen Wax @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5.3
+initial_exposure_time = 40
+material_type = Tough
+material_vendor = BlueCast
+material_colour = #007EFD
+
+[sla_material:NextDent Model 2.0 Grey @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 4
+initial_exposure_time = 28
+material_type = Dental
+material_vendor = NextDent
+material_colour = #C0C0C0
+
+[sla_material:NextDent Cast Purple @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3
+initial_exposure_time = 16
+material_type = Casting
+material_vendor = NextDent
+material_colour = #E800E8
+
+[sla_material:Siraya Tech Tenacious @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.7
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #F8F8F8
+
+[sla_material:Siraya Tech Blu Clear V2 @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #F8F8F8
+
+[sla_material:Siraya Tech Blu Blue @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 4
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #007EFD
+
+[sla_material:Siraya Tech Fast Black @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #595959
+
+[sla_material:Siraya Tech Fast Grey @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #C0C0C0
+
+[sla_material:Siraya Tech Simple Clear @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #F8F8F8
+
+[sla_material:Siraya Tech Sculpt @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.7
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Siraya Tech
+material_colour = #C0C0C0
+
+[sla_material:Harz Labs Model Resin Cherry @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 4.3
+initial_exposure_time = 16
+material_type = Tough
+material_vendor = Harz Labs
+material_colour = #EC0000
+
+[sla_material:Harz Labs Model Resin Black @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 4.3
+initial_exposure_time = 16
+material_type = Tough
+material_vendor = Harz Labs
+material_colour = #595959
+
+[sla_material:Harz Labs Basic Resin Red @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 4.3
+initial_exposure_time = 16
+material_type = Tough
+material_vendor = Harz Labs
+material_colour = #EC0000
+
+[sla_material:Resinworks 3D Violet @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5.7
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Resinworks 3D
+material_colour = #E800E8
+
+[sla_material:FunToDo Industrial Blend Unpigmented @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 1.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = FunToDo
+material_colour = #F8F8F8
+
+[sla_material:FunToDo Snow White @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = FunToDo
+material_colour = #FFFFFF
+
+[sla_material:FunToDo Ash Grey @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3
+initial_exposure_time = 32
+material_type = Tough
+material_vendor = FunToDo
+material_colour = #808080
+
+[sla_material:Ameralabs AMD 3 LED @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 1.7
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Ameralabs
+material_colour = #808080
+
+[sla_material:Dragon Resin Metalshine Metal Grey @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 10
+initial_exposure_time = 40
+material_type = Tough
+material_vendor = Dragon Resin
+material_colour = #808080
+
+[sla_material:Dragon Resin Metalshine Dark Brass @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 10
+initial_exposure_time = 40
+material_type = Tough
+material_vendor = Dragon Resin
+material_colour = #B0B000
+
+[sla_material:Dragon Resin Metalshine Brass @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 10
+initial_exposure_time = 40
+material_type = Tough
+material_vendor = Dragon Resin
+material_colour = #B0B000
+
+[sla_material:Esun Bio-Photopolymer Resin White @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.7
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Esun
+material_colour = #FFFFFF
+
+[sla_material:Esun Standard Resin Black @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.3
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Esun
+material_colour = #595959
+
+[sla_material:Monocure 3D Black Rapid Resin @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Monocure
+material_colour = #595959
+
+[sla_material:Monocure 3D Blue Rapid Resin @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Monocure
+material_colour = #007EFD
+
+[sla_material:Monocure 3D Clear Rapid Resin @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 2.7
+initial_exposure_time = 32
+material_type = Tough
+material_vendor = Monocure
+material_colour = #F8F8F8
+
+[sla_material:Monocure 3D Grey Rapid Resin @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 25
+material_type = Tough
+material_vendor = Monocure
+material_colour = #C0C0C0
+
+[sla_material:Monocure 3D White Rapid Resin @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 3.3
+initial_exposure_time = 28
+material_type = Tough
+material_vendor = Monocure
+material_colour = #FFFFFF
+
+[sla_material:Photocentric Hard Grey @0.05 SL1S]
+inherits = *0.05_sl1s*
+exposure_time = 5
+initial_exposure_time = 24
+material_type = Tough
+material_vendor = Photocentric
+material_colour = #808080
+
## 0.1 SL1S
## Prusa Polymers 0.1
diff --git a/resources/shaders/background_attr.vs b/resources/shaders/background_attr.vs
new file mode 100644
index 000000000..9b56ab43a
--- /dev/null
+++ b/resources/shaders/background_attr.vs
@@ -0,0 +1,12 @@
+#version 110
+
+attribute vec3 v_position;
+attribute vec2 v_tex_coord;
+
+varying vec2 tex_coord;
+
+void main()
+{
+ tex_coord = v_tex_coord;
+ gl_Position = vec4(v_position, 1.0);
+}
diff --git a/resources/shaders/flat_attr.vs b/resources/shaders/flat_attr.vs
new file mode 100644
index 000000000..370eedb72
--- /dev/null
+++ b/resources/shaders/flat_attr.vs
@@ -0,0 +1,11 @@
+#version 110
+
+attribute vec3 v_position;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+
+void main()
+{
+ gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
+}
diff --git a/resources/shaders/flat_texture_attr.vs b/resources/shaders/flat_texture_attr.vs
new file mode 100644
index 000000000..e59a99da3
--- /dev/null
+++ b/resources/shaders/flat_texture_attr.vs
@@ -0,0 +1,15 @@
+#version 110
+
+attribute vec3 v_position;
+attribute vec2 v_tex_coord;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+
+varying vec2 tex_coord;
+
+void main()
+{
+ tex_coord = v_tex_coord;
+ gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
+}
diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs
index b9e860d10..511faf4c0 100644
--- a/resources/shaders/gouraud.fs
+++ b/resources/shaders/gouraud.fs
@@ -40,7 +40,6 @@ varying vec2 intensity;
uniform PrintVolumeDetection print_volume;
-varying vec4 model_pos;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
diff --git a/resources/shaders/gouraud.vs b/resources/shaders/gouraud.vs
index 79d7a63c0..c8b3d7b33 100644
--- a/resources/shaders/gouraud.vs
+++ b/resources/shaders/gouraud.vs
@@ -38,7 +38,6 @@ varying vec2 intensity;
varying vec3 clipping_planes_dots;
-varying vec4 model_pos;
varying vec4 world_pos;
varying float world_normal_z;
varying vec3 eye_normal;
@@ -60,7 +59,6 @@ void main()
NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
- model_pos = gl_Vertex;
// Point in homogenous coordinates.
world_pos = volume_world_matrix * gl_Vertex;
diff --git a/resources/shaders/gouraud_attr.vs b/resources/shaders/gouraud_attr.vs
new file mode 100644
index 000000000..87e524c14
--- /dev/null
+++ b/resources/shaders/gouraud_attr.vs
@@ -0,0 +1,77 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
+//#define LIGHT_FRONT_SHININESS 5.0
+
+#define INTENSITY_AMBIENT 0.3
+
+const vec3 ZERO = vec3(0.0, 0.0, 0.0);
+
+struct SlopeDetection
+{
+ bool actived;
+ float normal_z;
+ mat3 volume_world_normal_matrix;
+};
+
+attribute vec3 v_position;
+attribute vec3 v_normal;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+uniform mat3 normal_matrix;
+uniform mat4 volume_world_matrix;
+uniform SlopeDetection slope;
+
+// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
+uniform vec2 z_range;
+// Clipping plane - general orientation. Used by the SLA gizmo.
+uniform vec4 clipping_plane;
+
+// x = diffuse, y = specular;
+varying vec2 intensity;
+
+varying vec3 clipping_planes_dots;
+
+varying vec4 world_pos;
+varying float world_normal_z;
+varying vec3 eye_normal;
+
+void main()
+{
+ // First transform the normal into camera space and normalize the result.
+ eye_normal = normalize(normal_matrix * v_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
+
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec4 position = view_model_matrix * vec4(v_position, 1.0);
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular applied).
+ NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ // Point in homogenous coordinates.
+ world_pos = volume_world_matrix * vec4(v_position, 1.0);
+
+ // z component of normal vector in world coordinate used for slope shading
+ world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0;
+
+ gl_Position = projection_matrix * position;
+ // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
+ clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
+}
diff --git a/resources/shaders/gouraud_light_attr.vs b/resources/shaders/gouraud_light_attr.vs
new file mode 100644
index 000000000..2e1b5fb42
--- /dev/null
+++ b/resources/shaders/gouraud_light_attr.vs
@@ -0,0 +1,45 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+
+#define INTENSITY_AMBIENT 0.3
+
+attribute vec3 v_position;
+attribute vec3 v_normal;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+uniform mat3 normal_matrix;
+
+// x = tainted, y = specular;
+varying vec2 intensity;
+
+void main()
+{
+ // First transform the normal into camera space and normalize the result.
+ vec3 normal = normalize(normal_matrix * v_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
+
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec4 position = view_model_matrix * vec4(v_position, 1.0);
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular applied).
+ NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ gl_Position = projection_matrix * position;
+}
diff --git a/resources/shaders/gouraud_light_instanced_attr.vs b/resources/shaders/gouraud_light_instanced_attr.vs
new file mode 100644
index 000000000..7069feb65
--- /dev/null
+++ b/resources/shaders/gouraud_light_instanced_attr.vs
@@ -0,0 +1,50 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+
+#define INTENSITY_AMBIENT 0.3
+
+// vertex attributes
+attribute vec3 v_position;
+attribute vec3 v_normal;
+// instance attributes
+attribute vec3 i_offset;
+attribute vec2 i_scales;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+uniform mat3 normal_matrix;
+
+// x = tainted, y = specular;
+varying vec2 intensity;
+
+void main()
+{
+ // First transform the normal into camera space and normalize the result.
+ vec3 eye_normal = normalize(normal_matrix * v_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
+
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec4 world_position = vec4(v_position * vec3(vec2(1.5 * i_scales.x), 1.5 * i_scales.y) + i_offset - vec3(0.0, 0.0, 0.5 * i_scales.y), 1.0);
+ vec4 eye_position = view_model_matrix * world_position;
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(eye_position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular applied).
+ NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ gl_Position = projection_matrix * eye_position;
+}
diff --git a/resources/shaders/mm_contour_attr.fs b/resources/shaders/mm_contour_attr.fs
new file mode 100644
index 000000000..14477a59e
--- /dev/null
+++ b/resources/shaders/mm_contour_attr.fs
@@ -0,0 +1,13 @@
+#version 110
+
+const float EPSILON = 0.0001;
+
+uniform vec4 uniform_color;
+
+void main()
+{
+ gl_FragColor = uniform_color;
+ // Values inside depth buffer for fragments of the contour of a selected area are offset
+ // by small epsilon to solve z-fighting between painted triangles and contour lines.
+ gl_FragDepth = gl_FragCoord.z - EPSILON;
+}
diff --git a/resources/shaders/mm_contour_attr.vs b/resources/shaders/mm_contour_attr.vs
new file mode 100644
index 000000000..370eedb72
--- /dev/null
+++ b/resources/shaders/mm_contour_attr.vs
@@ -0,0 +1,11 @@
+#version 110
+
+attribute vec3 v_position;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+
+void main()
+{
+ gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
+}
diff --git a/resources/shaders/mm_gouraud_attr.fs b/resources/shaders/mm_gouraud_attr.fs
new file mode 100644
index 000000000..78181e1d7
--- /dev/null
+++ b/resources/shaders/mm_gouraud_attr.fs
@@ -0,0 +1,63 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+
+#define INTENSITY_AMBIENT 0.3
+
+const vec3 ZERO = vec3(0.0, 0.0, 0.0);
+const float EPSILON = 0.0001;
+
+uniform vec4 uniform_color;
+
+uniform bool volume_mirrored;
+
+uniform mat4 view_model_matrix;
+uniform mat3 normal_matrix;
+
+varying vec3 clipping_planes_dots;
+varying vec4 model_pos;
+
+void main()
+{
+ if (any(lessThan(clipping_planes_dots, ZERO)))
+ discard;
+ vec3 color = uniform_color.rgb;
+ float alpha = uniform_color.a;
+
+ vec3 triangle_normal = normalize(cross(dFdx(model_pos.xyz), dFdy(model_pos.xyz)));
+#ifdef FLIP_TRIANGLE_NORMALS
+ triangle_normal = -triangle_normal;
+#endif
+
+ if (volume_mirrored)
+ triangle_normal = -triangle_normal;
+
+ // First transform the normal into camera space and normalize the result.
+ vec3 eye_normal = normalize(normal_matrix * triangle_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0);
+
+ // x = diffuse, y = specular;
+ vec2 intensity = vec2(0.0);
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec3 position = (view_model_matrix * model_pos).xyz;
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular applied).
+ NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0);
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ gl_FragColor = vec4(vec3(intensity.y) + color * intensity.x, alpha);
+}
diff --git a/resources/shaders/mm_gouraud_attr.vs b/resources/shaders/mm_gouraud_attr.vs
new file mode 100644
index 000000000..76101b767
--- /dev/null
+++ b/resources/shaders/mm_gouraud_attr.vs
@@ -0,0 +1,28 @@
+#version 110
+
+const vec3 ZERO = vec3(0.0, 0.0, 0.0);
+
+attribute vec3 v_position;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+
+uniform mat4 volume_world_matrix;
+// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane.
+uniform vec2 z_range;
+// Clipping plane - general orientation. Used by the SLA gizmo.
+uniform vec4 clipping_plane;
+
+varying vec3 clipping_planes_dots;
+varying vec4 model_pos;
+
+void main()
+{
+ model_pos = vec4(v_position, 1.0);
+ // Point in homogenous coordinates.
+ vec4 world_pos = volume_world_matrix * model_pos;
+
+ gl_Position = projection_matrix * view_model_matrix * model_pos;
+ // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded.
+ clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z);
+}
diff --git a/resources/shaders/options_110.fs b/resources/shaders/options_110.fs
deleted file mode 100644
index ab656998d..000000000
--- a/resources/shaders/options_110.fs
+++ /dev/null
@@ -1,8 +0,0 @@
-#version 110
-
-uniform vec4 uniform_color;
-
-void main()
-{
- gl_FragColor = uniform_color;
-}
diff --git a/resources/shaders/options_110.vs b/resources/shaders/options_110.vs
deleted file mode 100644
index 5f2ab2350..000000000
--- a/resources/shaders/options_110.vs
+++ /dev/null
@@ -1,22 +0,0 @@
-#version 110
-
-uniform bool use_fixed_screen_size;
-uniform float zoom;
-uniform float point_size;
-uniform float near_plane_height;
-
-float fixed_screen_size()
-{
- return point_size;
-}
-
-float fixed_world_size()
-{
- return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
-}
-
-void main()
-{
- gl_Position = ftransform();
- gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
-}
diff --git a/resources/shaders/options_120.fs b/resources/shaders/options_120.fs
deleted file mode 100644
index e9b61304f..000000000
--- a/resources/shaders/options_120.fs
+++ /dev/null
@@ -1,22 +0,0 @@
-// version 120 is needed for gl_PointCoord
-#version 120
-
-uniform vec4 uniform_color;
-uniform float percent_outline_radius;
-uniform float percent_center_radius;
-
-vec4 calc_color(float radius, vec4 color)
-{
- return ((radius < percent_center_radius) || (radius > 1.0 - percent_outline_radius)) ?
- vec4(0.5 * color.rgb, color.a) : color;
-}
-
-void main()
-{
- vec2 pos = (gl_PointCoord - 0.5) * 2.0;
- float radius = length(pos);
- if (radius > 1.0)
- discard;
-
- gl_FragColor = calc_color(radius, uniform_color);
-}
diff --git a/resources/shaders/options_120.vs b/resources/shaders/options_120.vs
deleted file mode 100644
index edb503fb2..000000000
--- a/resources/shaders/options_120.vs
+++ /dev/null
@@ -1,22 +0,0 @@
-#version 120
-
-uniform bool use_fixed_screen_size;
-uniform float zoom;
-uniform float point_size;
-uniform float near_plane_height;
-
-float fixed_screen_size()
-{
- return point_size;
-}
-
-float fixed_world_size()
-{
- return (gl_Position.w == 1.0) ? zoom * near_plane_height * point_size : near_plane_height * point_size / gl_Position.w;
-}
-
-void main()
-{
- gl_Position = ftransform();
- gl_PointSize = use_fixed_screen_size ? fixed_screen_size() : fixed_world_size();
-}
diff --git a/resources/shaders/printbed.fs b/resources/shaders/printbed.fs
index bef075158..833dff08f 100644
--- a/resources/shaders/printbed.fs
+++ b/resources/shaders/printbed.fs
@@ -7,15 +7,15 @@ uniform sampler2D texture;
uniform bool transparent_background;
uniform bool svg_source;
-varying vec2 tex_coords;
+varying vec2 tex_coord;
vec4 svg_color()
{
// takes foreground from texture
- vec4 fore_color = texture2D(texture, tex_coords);
+ vec4 fore_color = texture2D(texture, tex_coord);
// calculates radial gradient
- vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coords.xy) - vec2(0.5)))));
+ vec3 back_color = vec3(mix(back_color_light, back_color_dark, smoothstep(0.0, 0.5, length(abs(tex_coord.xy) - vec2(0.5)))));
// blends foreground with background
return vec4(mix(back_color, fore_color.rgb, fore_color.a), transparent_background ? fore_color.a : 1.0);
@@ -24,7 +24,7 @@ vec4 svg_color()
vec4 non_svg_color()
{
// takes foreground from texture
- vec4 color = texture2D(texture, tex_coords);
+ vec4 color = texture2D(texture, tex_coord);
return vec4(color.rgb, transparent_background ? color.a * 0.25 : color.a);
}
diff --git a/resources/shaders/printbed.vs b/resources/shaders/printbed.vs
index 3b3f8875d..27addc752 100644
--- a/resources/shaders/printbed.vs
+++ b/resources/shaders/printbed.vs
@@ -1,9 +1,9 @@
#version 110
-varying vec2 tex_coords;
+varying vec2 tex_coord;
void main()
{
gl_Position = ftransform();
- tex_coords = gl_MultiTexCoord0.xy;
+ tex_coord = gl_MultiTexCoord0.xy;
}
diff --git a/resources/shaders/printbed_attr.vs b/resources/shaders/printbed_attr.vs
new file mode 100644
index 000000000..e59a99da3
--- /dev/null
+++ b/resources/shaders/printbed_attr.vs
@@ -0,0 +1,15 @@
+#version 110
+
+attribute vec3 v_position;
+attribute vec2 v_tex_coord;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+
+varying vec2 tex_coord;
+
+void main()
+{
+ tex_coord = v_tex_coord;
+ gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0);
+}
diff --git a/resources/shaders/toolpaths_cog_attr.vs b/resources/shaders/toolpaths_cog_attr.vs
new file mode 100644
index 000000000..5951238b7
--- /dev/null
+++ b/resources/shaders/toolpaths_cog_attr.vs
@@ -0,0 +1,47 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31)
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+// normalized values for (1./1.43, 0.2/1.43, 1./1.43)
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+
+#define INTENSITY_AMBIENT 0.3
+
+attribute vec3 v_position;
+attribute vec3 v_normal;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+uniform mat3 normal_matrix;
+
+// x = tainted, y = specular;
+varying vec2 intensity;
+varying vec3 world_position;
+
+void main()
+{
+ // First transform the normal into camera space and normalize the result.
+ vec3 normal = normalize(normal_matrix * v_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
+
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec4 position = view_model_matrix * vec4(v_position, 1.0);
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular applied).
+ NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ world_position = v_position;
+ gl_Position = projection_matrix * position;
+}
diff --git a/resources/shaders/variable_layer_height_attr.vs b/resources/shaders/variable_layer_height_attr.vs
new file mode 100644
index 000000000..40609bd0d
--- /dev/null
+++ b/resources/shaders/variable_layer_height_attr.vs
@@ -0,0 +1,60 @@
+#version 110
+
+#define INTENSITY_CORRECTION 0.6
+
+const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929);
+#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION)
+#define LIGHT_TOP_SHININESS 20.0
+
+const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074);
+#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION)
+//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION)
+//#define LIGHT_FRONT_SHININESS 5.0
+
+#define INTENSITY_AMBIENT 0.3
+
+attribute vec3 v_position;
+attribute vec3 v_normal;
+attribute vec2 v_tex_coord;
+
+uniform mat4 view_model_matrix;
+uniform mat4 projection_matrix;
+uniform mat3 normal_matrix;
+uniform mat4 volume_world_matrix;
+uniform float object_max_z;
+
+// x = tainted, y = specular;
+varying vec2 intensity;
+
+varying float object_z;
+
+void main()
+{
+ // =====================================================
+ // NOTE:
+ // when object_max_z > 0.0 we are rendering the overlay
+ // when object_max_z == 0.0 we are rendering the volumes
+ // =====================================================
+
+ // First transform the normal into camera space and normalize the result.
+ vec3 normal = (object_max_z > 0.0) ? vec3(0.0, 0.0, 1.0) : normalize(normal_matrix * v_normal);
+
+ // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex.
+ // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range.
+ float NdotL = max(dot(normal, LIGHT_TOP_DIR), 0.0);
+
+ intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE;
+ vec4 position = view_model_matrix * vec4(v_position, 1.0);
+ intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, normal)), 0.0), LIGHT_TOP_SHININESS);
+
+ // Perform the same lighting calculation for the 2nd light source (no specular)
+ NdotL = max(dot(normal, LIGHT_FRONT_DIR), 0.0);
+
+ intensity.x += NdotL * LIGHT_FRONT_DIFFUSE;
+
+ // Scaled to widths of the Z texture.
+ object_z = (object_max_z > 0.0) ? object_max_z * v_tex_coord.y : (volume_world_matrix * vec4(v_position, 1.0)).z;
+
+ gl_Position = projection_matrix * position;
+}
diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp
index 0fec89ced..f48d7ff0a 100644
--- a/src/libslic3r/Brim.cpp
+++ b/src/libslic3r/Brim.cpp
@@ -313,7 +313,7 @@ static std::vector inner_brim_area(const Print
// After 7ff76d07684858fd937ef2f5d863f105a10f798e offset and shrink don't work with CW polygons (holes), so let's make it CCW.
Polygons ex_poly_holes_reversed = ex_poly.holes;
polygons_reverse(ex_poly_holes_reversed);
- for (const PrintInstance &instance : object->instances()) {
+ for ([[maybe_unused]] const PrintInstance &instance : object->instances()) {
++polygon_idx; // Increase idx because of the contour of the ExPolygon.
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner)
diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp
index be8d224c3..b4ac118ec 100644
--- a/src/libslic3r/BuildVolume.hpp
+++ b/src/libslic3r/BuildVolume.hpp
@@ -95,10 +95,10 @@ public:
bool all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& bbox, bool ignore_bottom = true) const;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
const std::pair, std::vector>& top_bottom_convex_hull_decomposition_scene() const { return m_top_bottom_convex_hull_decomposition_scene; }
const std::pair, std::vector>& top_bottom_convex_hull_decomposition_bed() const { return m_top_bottom_convex_hull_decomposition_bed; }
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
// Source definition of the print bed geometry (PrintConfig::bed_shape)
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 6be35a8c8..ad32f5fac 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1155,13 +1155,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
}
print.throw_if_canceled();
- // Starting now, the G-code find / replace post-processor will be enabled.
- file.find_replace_enable();
-
// adds tags for time estimators
if (print.config().remaining_times.value)
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::First_Line_M73_Placeholder).c_str());
+ // Starting now, the G-code find / replace post-processor will be enabled.
+ file.find_replace_enable();
+
// Prepare the helper object for replacing placeholders in custom G-code and output filename.
m_placeholder_parser = print.placeholder_parser();
m_placeholder_parser.update_timestamp();
@@ -1442,6 +1442,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write(m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
file.write(m_writer.postamble());
+ // From now to the end of G-code, the G-code find / replace post-processor will be disabled.
+ // Thus the PrusaSlicer generated config will NOT be processed by the G-code post-processor, see GH issue #7952.
+ file.find_replace_supress();
+
// adds tags for time estimators
if (print.config().remaining_times.value)
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Last_Line_M73_Placeholder).c_str());
@@ -1464,10 +1468,6 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
file.write_format("; total toolchanges = %i\n", print.m_print_statistics.total_toolchanges);
file.write_format(";%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Estimated_Printing_Time_Placeholder).c_str());
- // From now to the end of G-code, the G-code find / replace post-processor will be disabled.
- // Thus the PrusaSlicer generated config will NOT be processed by the G-code post-processor, see GH issue #7952.
- file.find_replace_supress();
-
// Append full config, delimited by two 'phony' configuration keys prusaslicer_config = begin and prusaslicer_config = end.
// The delimiters are structured as configuration key / value pairs to be parsable by older versions of PrusaSlicer G-code viewer.
{
diff --git a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp
index f846d8cec..9edb35ee8 100644
--- a/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp
+++ b/src/libslic3r/GCode/AvoidCrossingPerimeters.cpp
@@ -13,6 +13,8 @@
#include
#include
+//#define AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT
+
namespace Slic3r {
struct TravelPoint
@@ -354,8 +356,6 @@ static Polyline to_polyline(const std::vector &travel)
return result;
}
-// #define AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT
-
#ifdef AVOID_CROSSING_PERIMETERS_DEBUG_OUTPUT
static void export_travel_to_svg(const Polygons &boundary,
const Line &original_travel,
@@ -521,6 +521,25 @@ static float get_perimeter_spacing_external(const Layer &layer)
return perimeter_spacing;
}
+// Returns average perimeter width calculated from all LayerRegion within the layer.
+static float get_external_perimeter_width(const Layer &layer)
+{
+ size_t regions_count = 0;
+ float perimeter_width = 0.f;
+ for (const LayerRegion *layer_region : layer.regions())
+ if (layer_region != nullptr && !layer_region->slices.empty()) {
+ perimeter_width += float(layer_region->flow(frExternalPerimeter).scaled_width());
+ ++regions_count;
+ }
+
+ assert(perimeter_width >= 0.f);
+ if (regions_count != 0)
+ perimeter_width /= float(regions_count);
+ else
+ perimeter_width = get_default_perimeter_spacing(*layer.object());
+ return perimeter_width;
+}
+
// Called by avoid_perimeters() and by simplify_travel_heuristics().
static size_t avoid_perimeters_inner(const AvoidCrossingPerimeters::Boundary &boundary,
const Point &start,
@@ -659,22 +678,22 @@ static size_t avoid_perimeters(const AvoidCrossingPerimeters::Boundary &boundary
// Check if anyone of ExPolygons contains whole travel.
// called by need_wipe() and AvoidCrossingPerimeters::travel_to()
// FIXME Lukas H.: Maybe similar approach could also be used for ExPolygon::contains()
-static bool any_expolygon_contains(const ExPolygons &ex_polygons,
- const std::vector &ex_polygons_bboxes,
- const EdgeGrid::Grid &grid_lslice,
+static bool any_expolygon_contains(const ExPolygons &lslices_offset,
+ const std::vector &lslices_offset_bboxes,
+ const EdgeGrid::Grid &grid_lslices_offset,
const Line &travel)
{
- assert(ex_polygons.size() == ex_polygons_bboxes.size());
- if(!grid_lslice.bbox().contains(travel.a) || !grid_lslice.bbox().contains(travel.b))
+ assert(lslices_offset.size() == lslices_offset_bboxes.size());
+ if(!grid_lslices_offset.bbox().contains(travel.a) || !grid_lslices_offset.bbox().contains(travel.b))
return false;
- FirstIntersectionVisitor visitor(grid_lslice);
+ FirstIntersectionVisitor visitor(grid_lslices_offset);
visitor.pt_current = &travel.a;
visitor.pt_next = &travel.b;
- grid_lslice.visit_cells_intersecting_line(*visitor.pt_current, *visitor.pt_next, visitor);
+ grid_lslices_offset.visit_cells_intersecting_line(*visitor.pt_current, *visitor.pt_next, visitor);
if (!visitor.intersect) {
- for (const ExPolygon &ex_polygon : ex_polygons) {
- const BoundingBox &bbox = ex_polygons_bboxes[&ex_polygon - &ex_polygons.front()];
+ for (const ExPolygon &ex_polygon : lslices_offset) {
+ const BoundingBox &bbox = lslices_offset_bboxes[&ex_polygon - &lslices_offset.front()];
if (bbox.contains(travel.a) && bbox.contains(travel.b) && ex_polygon.contains(travel.a))
return true;
}
@@ -684,18 +703,18 @@ static bool any_expolygon_contains(const ExPolygons &ex_polygons,
// Check if anyone of ExPolygons contains whole travel.
// called by need_wipe()
-static bool any_expolygon_contains(const ExPolygons &ex_polygons, const std::vector &ex_polygons_bboxes, const EdgeGrid::Grid &grid_lslice, const Polyline &travel)
+static bool any_expolygon_contains(const ExPolygons &ex_polygons, const std::vector &ex_polygons_bboxes, const EdgeGrid::Grid &grid_lslice_offset, const Polyline &travel)
{
assert(ex_polygons.size() == ex_polygons_bboxes.size());
- if(std::any_of(travel.points.begin(), travel.points.end(), [&grid_lslice](const Point &point) { return !grid_lslice.bbox().contains(point); }))
+ if(std::any_of(travel.points.begin(), travel.points.end(), [&grid_lslice_offset](const Point &point) { return !grid_lslice_offset.bbox().contains(point); }))
return false;
- FirstIntersectionVisitor visitor(grid_lslice);
+ FirstIntersectionVisitor visitor(grid_lslice_offset);
bool any_intersection = false;
for (size_t line_idx = 1; line_idx < travel.size(); ++line_idx) {
visitor.pt_current = &travel.points[line_idx - 1];
visitor.pt_next = &travel.points[line_idx];
- grid_lslice.visit_cells_intersecting_line(*visitor.pt_current, *visitor.pt_next, visitor);
+ grid_lslice_offset.visit_cells_intersecting_line(*visitor.pt_current, *visitor.pt_next, visitor);
any_intersection = visitor.intersect;
if (any_intersection) break;
}
@@ -711,14 +730,14 @@ static bool any_expolygon_contains(const ExPolygons &ex_polygons, const std::vec
return false;
}
-static bool need_wipe(const GCode &gcodegen,
- const EdgeGrid::Grid &grid_lslice,
- const Line &original_travel,
- const Polyline &result_travel,
- const size_t intersection_count)
+static bool need_wipe(const GCode &gcodegen,
+ const ExPolygons &lslices_offset,
+ const std::vector &lslices_offset_bboxes,
+ const EdgeGrid::Grid &grid_lslices_offset,
+ const Line &original_travel,
+ const Polyline &result_travel,
+ const size_t intersection_count)
{
- const ExPolygons &lslices = gcodegen.layer()->lslices;
- const std::vector &lslices_bboxes = gcodegen.layer()->lslices_bboxes;
bool z_lift_enabled = gcodegen.config().retract_lift.get_at(gcodegen.writer().extruder()->id()) > 0.;
bool wipe_needed = false;
@@ -728,16 +747,16 @@ static bool need_wipe(const GCode &gcodegen,
// The original layer is intersected with defined boundaries. Then it is necessary to make a detailed test.
// If the z-lift is enabled, then a wipe is needed when the original travel leads above the holes.
if (z_lift_enabled) {
- if (any_expolygon_contains(lslices, lslices_bboxes, grid_lslice, original_travel)) {
+ if (any_expolygon_contains(lslices_offset, lslices_offset_bboxes, grid_lslices_offset, original_travel)) {
// Check if original_travel and result_travel are not same.
// If both are the same, then it is possible to skip testing of result_travel
wipe_needed = !(result_travel.size() > 2 && result_travel.first_point() == original_travel.a && result_travel.last_point() == original_travel.b) &&
- !any_expolygon_contains(lslices, lslices_bboxes, grid_lslice, result_travel);
+ !any_expolygon_contains(lslices_offset, lslices_offset_bboxes, grid_lslices_offset, result_travel);
} else {
wipe_needed = true;
}
} else {
- wipe_needed = !any_expolygon_contains(lslices, lslices_bboxes, grid_lslice, result_travel);
+ wipe_needed = !any_expolygon_contains(lslices_offset, lslices_offset_bboxes, grid_lslices_offset, result_travel);
}
}
@@ -1163,10 +1182,8 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
Vec2d startf = start.cast();
Vec2d endf = end .cast();
- const ExPolygons &lslices = gcodegen.layer()->lslices;
- const std::vector &lslices_bboxes = gcodegen.layer()->lslices_bboxes;
- bool is_support_layer = dynamic_cast(gcodegen.layer()) != nullptr;
- if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) {
+ bool is_support_layer = dynamic_cast(gcodegen.layer()) != nullptr;
+ if (!use_external && (is_support_layer || (!m_lslices_offset.empty() && !any_expolygon_contains(m_lslices_offset, m_lslices_offset_bboxes, m_grid_lslices_offset, travel)))) {
// Initialize m_internal only when it is necessary.
if (m_internal.boundaries.empty())
init_boundary(&m_internal, to_polygons(get_boundary(*gcodegen.layer())));
@@ -1216,7 +1233,7 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
} else if (max_detour_length_exceeded) {
*could_be_wipe_disabled = false;
} else
- *could_be_wipe_disabled = !need_wipe(gcodegen, m_grid_lslice, travel, result_pl, travel_intersection_count);
+ *could_be_wipe_disabled = !need_wipe(gcodegen, m_lslices_offset, m_lslices_offset_bboxes, m_grid_lslices_offset, travel, result_pl, travel_intersection_count);
return result_pl;
}
@@ -1227,13 +1244,21 @@ void AvoidCrossingPerimeters::init_layer(const Layer &layer)
{
m_internal.clear();
m_external.clear();
+ m_lslices_offset.clear();
+ m_lslices_offset_bboxes.clear();
+
+ float perimeter_offset = -get_external_perimeter_width(layer) / float(2.);
+ m_lslices_offset = offset_ex(layer.lslices, perimeter_offset);
+
+ m_lslices_offset_bboxes.reserve(m_lslices_offset.size());
+ for (const ExPolygon &ex_poly : m_lslices_offset)
+ m_lslices_offset_bboxes.emplace_back(get_extents(ex_poly));
BoundingBox bbox_slice(get_extents(layer.lslices));
bbox_slice.offset(SCALED_EPSILON);
- m_grid_lslice.set_bbox(bbox_slice);
- //FIXME 1mm grid?
- m_grid_lslice.create(layer.lslices, coord_t(scale_(1.)));
+ m_grid_lslices_offset.set_bbox(bbox_slice);
+ m_grid_lslices_offset.create(m_lslices_offset, coord_t(scale_(1.)));
}
#if 0
diff --git a/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp b/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
index 412822c66..eb81c7972 100644
--- a/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
+++ b/src/libslic3r/GCode/AvoidCrossingPerimeters.hpp
@@ -58,8 +58,11 @@ private:
// we enable it by default for the first travel move in print
bool m_disabled_once { true };
+ // Lslices offseted by half an external perimeter width. Used for detection if line or polyline is inside of any polygon.
+ ExPolygons m_lslices_offset;
+ std::vector m_lslices_offset_bboxes;
// Used for detection of line or polyline is inside of any polygon.
- EdgeGrid::Grid m_grid_lslice;
+ EdgeGrid::Grid m_grid_lslices_offset;
// Store all needed data for travels inside object
Boundary m_internal;
// Store all needed data for travels outside object
diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 03abc386a..c306cccc4 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -66,10 +66,12 @@
#define ENABLE_OBJECT_MANIPULATOR_FOCUS (1 && ENABLE_2_5_0_ALPHA1)
// Enable removal of wipe tower magic object_id equal to 1000
#define ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
-// Enable removal of old OpenGL render calls
-#define ENABLE_GLBEGIN_GLEND_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
-// Enable replace GLIndexedVertexArray with GLModel
-#define ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL (1 && ENABLE_GLBEGIN_GLEND_REMOVAL)
+// Enable removal of legacy OpenGL calls
+#define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1)
+// Enable using vertex attributes and matrices in shaders
+#define ENABLE_GL_SHADERS_ATTRIBUTES (1 && ENABLE_LEGACY_OPENGL_REMOVAL)
+// Shows an imgui dialog with GLModel statistics data
+#define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL)
// Enable show non-manifold edges
#define ENABLE_SHOW_NON_MANIFOLD_EDGES (1 && ENABLE_2_5_0_ALPHA1)
// Enable rework of Reload from disk command
diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt
index 022bba2a8..aa6268d88 100644
--- a/src/slic3r/CMakeLists.txt
+++ b/src/slic3r/CMakeLists.txt
@@ -193,7 +193,6 @@ set(SLIC3R_GUI_SOURCES
GUI/Mouse3DController.hpp
GUI/DoubleSlider.cpp
GUI/DoubleSlider.hpp
- GUI/DoubleSlider_Utils.hpp
GUI/Notebook.cpp
GUI/Notebook.hpp
GUI/ObjectDataViewModel.cpp
diff --git a/src/slic3r/GUI/3DBed.cpp b/src/slic3r/GUI/3DBed.cpp
index 244a802db..177c508ad 100644
--- a/src/slic3r/GUI/3DBed.cpp
+++ b/src/slic3r/GUI/3DBed.cpp
@@ -11,6 +11,10 @@
#include "GUI_App.hpp"
#include "GLCanvas3D.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "Plater.hpp"
+#include "Camera.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#include
@@ -27,7 +31,7 @@ static const Slic3r::ColorRGBA DEFAULT_TRANSPARENT_GRID_COLOR = { 0.9f, 0.9f, 0
namespace Slic3r {
namespace GUI {
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
bool GeometryBuffer::set_from_triangles(const std::vector &triangles, float z)
{
if (triangles.empty()) {
@@ -96,7 +100,7 @@ const float* GeometryBuffer::get_vertices_data() const
{
return (m_vertices.size() > 0) ? (const float*)m_vertices.data() : nullptr;
}
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
const float Bed3D::Axes::DefaultStemRadius = 0.5f;
const float Bed3D::Axes::DefaultStemLength = 25.0f;
@@ -105,17 +109,32 @@ const float Bed3D::Axes::DefaultTipLength = 5.0f;
void Bed3D::Axes::render()
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto render_axis = [this](GLShaderProgram* shader, const Transform3d& transform) {
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d matrix = camera.get_view_matrix() * transform;
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
auto render_axis = [this](const Transform3f& transform) {
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(transform.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_arrow.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
};
if (!m_arrow.is_initialized())
m_arrow.init_from(stilized_arrow(16, DefaultTipRadius, DefaultTipLength, DefaultStemRadius, m_stem_length));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -125,28 +144,40 @@ void Bed3D::Axes::render()
shader->set_uniform("emission_factor", 0.0f);
// x axis
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::X());
#else
m_arrow.set_color(-1, ColorRGBA::X());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_axis(shader, Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }));
+#else
render_axis(Geometry::assemble_transform(m_origin, { 0.0, 0.5 * M_PI, 0.0 }).cast());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// y axis
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Y());
#else
m_arrow.set_color(-1, ColorRGBA::Y());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_axis(shader, Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }));
+#else
render_axis(Geometry::assemble_transform(m_origin, { -0.5 * M_PI, 0.0, 0.0 }).cast());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// z axis
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_arrow.set_color(ColorRGBA::Z());
#else
m_arrow.set_color(-1, ColorRGBA::Z());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_axis(shader, Geometry::assemble_transform(m_origin));
+#else
render_axis(Geometry::assemble_transform(m_origin).cast());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->stop_using();
@@ -200,7 +231,7 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
m_model_filename = model_filename;
m_extended_bounding_box = this->calc_extended_bounding_box();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_contour = ExPolygon(Polygon::new_scale(bed_shape));
m_polygon = offset(m_contour.contour, (float)m_contour.contour.bounding_box().radius() * 1.7f, jtRound, scale_(0.5)).front();
@@ -217,7 +248,7 @@ bool Bed3D::set_shape(const Pointfs& bed_shape, const double max_print_height, c
m_polygon = offset(poly.contour, (float)bed_bbox.radius() * 1.7f, jtRound, scale_(0.5)).front();
this->release_VBOs();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_texture.reset();
m_model.reset();
@@ -239,6 +270,17 @@ Point Bed3D::point_projection(const Point& point) const
return m_polygon.point_projection(point);
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void Bed3D::render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture)
+{
+ render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture, false);
+}
+
+void Bed3D::render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor)
+{
+ render_internal(canvas, view_matrix, projection_matrix, bottom, scale_factor, false, false, true);
+}
+#else
void Bed3D::render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture)
{
render_internal(canvas, bottom, scale_factor, show_axes, show_texture, false);
@@ -248,9 +290,15 @@ void Bed3D::render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_fact
{
render_internal(canvas, bottom, scale_factor, false, false, true);
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void Bed3D::render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
+ bool show_axes, bool show_texture, bool picking)
+#else
void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
m_scale_factor = scale_factor;
@@ -259,17 +307,23 @@ void Bed3D::render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
glsafe(::glEnable(GL_DEPTH_TEST));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.set_color(picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
#else
m_model.set_color(-1, picking ? PICKING_MODEL_COLOR : DEFAULT_MODEL_COLOR);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
switch (m_type)
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ case Type::System: { render_system(canvas, view_matrix, projection_matrix, bottom, show_texture); break; }
+ default:
+ case Type::Custom: { render_custom(canvas, view_matrix, projection_matrix, bottom, show_texture, picking); break; }
+#else
case Type::System: { render_system(canvas, bottom, show_texture); break; }
default:
case Type::Custom: { render_custom(canvas, bottom, show_texture, picking); break; }
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
glsafe(::glDisable(GL_DEPTH_TEST));
@@ -298,7 +352,7 @@ BoundingBoxf3 Bed3D::calc_extended_bounding_box() const
return out;
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::init_triangles()
{
if (m_triangles.is_initialized())
@@ -312,7 +366,7 @@ void Bed3D::init_triangles()
return;
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2, GLModel::Geometry::index_type(triangles.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3T2 };
init_data.reserve_vertices(triangles.size());
init_data.reserve_indices(triangles.size() / 3);
@@ -336,12 +390,8 @@ void Bed3D::init_triangles()
const Vec3f p = { v.x(), v.y(), GROUND_Z };
init_data.add_vertex(p, (Vec2f)(v - min).cwiseProduct(inv_size).eval());
++vertices_counter;
- if (vertices_counter % 3 == 0) {
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
- else
- init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
- }
+ if (vertices_counter % 3 == 0)
+ init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
m_triangles.init_from(std::move(init_data));
@@ -380,18 +430,15 @@ void Bed3D::init_gridlines()
std::copy(contour_lines.begin(), contour_lines.end(), std::back_inserter(gridlines));
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * gridlines.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2 * gridlines.size());
init_data.reserve_indices(2 * gridlines.size());
- for (const Line& l : gridlines) {
+ for (const Slic3r::Line& l : gridlines) {
init_data.add_vertex(Vec3f(unscale(l.a.x()), unscale(l.a.y()), GROUND_Z));
init_data.add_vertex(Vec3f(unscale(l.b.x()), unscale(l.b.y()), GROUND_Z));
const unsigned int vertices_counter = (unsigned int)init_data.vertices_count();
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_line((unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
- else
- init_data.add_uint_line(vertices_counter - 2, vertices_counter - 1);
+ init_data.add_line(vertices_counter - 2, vertices_counter - 1);
}
m_gridlines.init_from(std::move(init_data));
@@ -429,7 +476,7 @@ void Bed3D::calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox)
if (!m_gridlines.set_from_lines(gridlines, GROUND_Z))
BOOST_LOG_TRIVIAL(error) << "Unable to create bed grid lines\n";
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Try to match the print bed shape with the shape of an active profile. If such a match exists,
// return the print bed model.
@@ -461,6 +508,16 @@ void Bed3D::render_axes()
m_axes.render();
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture)
+{
+ if (!bottom)
+ render_model(view_matrix, projection_matrix);
+
+ if (show_texture)
+ render_texture(bottom, canvas);
+}
+#else
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
{
if (!bottom)
@@ -469,6 +526,7 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
if (show_texture)
render_texture(bottom, canvas);
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
{
@@ -531,12 +589,21 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
canvas.request_extra_frame();
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
init_triangles();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("printbed_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("printbed");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->set_uniform("transparent_background", bottom);
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
@@ -593,10 +660,7 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
if (bottom)
glsafe(::glFrontFace(GL_CW));
- unsigned int stride = m_triangles.get_vertex_data_size();
-
- GLint position_id = shader->get_attrib_location("v_position");
- GLint tex_coords_id = shader->get_attrib_location("v_tex_coords");
+ const unsigned int stride = m_triangles.get_vertex_data_size();
// show the temporary texture while no compressed data is available
GLuint tex_id = (GLuint)m_temp_texture.get_id();
@@ -606,22 +670,16 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
glsafe(::glBindTexture(GL_TEXTURE_2D, tex_id));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id));
- if (position_id != -1) {
- glsafe(::glEnableVertexAttribArray(position_id));
- glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_position_offset()));
- }
- if (tex_coords_id != -1) {
- glsafe(::glEnableVertexAttribArray(tex_coords_id));
- glsafe(::glVertexAttribPointer(tex_coords_id, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)(intptr_t)m_triangles.get_tex_coords_offset()));
- }
+ glsafe(::glVertexPointer(3, GL_FLOAT, stride, (const void*)(intptr_t)m_triangles.get_position_offset()));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+
+ glsafe(::glTexCoordPointer(2, GL_FLOAT, stride, (const void*)(intptr_t)m_triangles.get_tex_coords_offset()));
+ glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
glsafe(::glDrawArrays(GL_TRIANGLES, 0, (GLsizei)m_triangles.get_vertices_count()));
- if (tex_coords_id != -1)
- glsafe(::glDisableVertexAttribArray(tex_coords_id));
-
- if (position_id != -1)
- glsafe(::glDisableVertexAttribArray(position_id));
+ glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
@@ -636,20 +694,24 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
shader->stop_using();
}
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void Bed3D::render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix)
+#else
void Bed3D::render_model()
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
if (m_model_filename.empty())
return;
if (m_model.get_filename() != m_model_filename && m_model.init_from_file(m_model_filename)) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.set_color(DEFAULT_MODEL_COLOR);
#else
m_model.set_color(-1, DEFAULT_MODEL_COLOR);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// move the model so that its origin (0.0, 0.0, 0.0) goes into the bed shape center and a bit down to avoid z-fighting with the texture quad
m_model_offset = to_3d(m_build_volume.bounding_volume2d().center(), -0.03);
@@ -659,20 +721,37 @@ void Bed3D::render_model()
}
if (!m_model.get_filename().empty()) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d matrix = view_matrix * Geometry::assemble_transform(m_model_offset);
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", projection_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_model_offset.x(), m_model_offset.y(), m_model_offset.z()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_model.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
shader->stop_using();
}
}
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void Bed3D::render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking)
+#else
void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
if (m_texture_filename.empty() && m_model_filename.empty()) {
render_default(bottom, picking);
@@ -680,7 +759,11 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
}
if (!bottom)
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_model(view_matrix, projection_matrix);
+#else
render_model();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (show_texture)
render_texture(bottom, canvas);
@@ -690,14 +773,24 @@ void Bed3D::render_default(bool bottom, bool picking)
{
m_texture.reset();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
init_gridlines();
init_triangles();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
glsafe(::glEnable(GL_DEPTH_TEST));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
@@ -756,10 +849,10 @@ void Bed3D::render_default(bool bottom, bool picking)
glsafe(::glDisable(GL_BLEND));
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void Bed3D::release_VBOs()
{
if (m_vbo_id > 0) {
@@ -767,7 +860,7 @@ void Bed3D::release_VBOs()
m_vbo_id = 0;
}
}
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
} // GUI
} // Slic3r
diff --git a/src/slic3r/GUI/3DBed.hpp b/src/slic3r/GUI/3DBed.hpp
index 350ae48f6..de4fa99cf 100644
--- a/src/slic3r/GUI/3DBed.hpp
+++ b/src/slic3r/GUI/3DBed.hpp
@@ -6,9 +6,9 @@
#include "GLModel.hpp"
#include "libslic3r/BuildVolume.hpp"
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/ExPolygon.hpp"
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include
#include
@@ -18,7 +18,7 @@ namespace GUI {
class GLCanvas3D;
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
class GeometryBuffer
{
struct Vertex
@@ -40,7 +40,7 @@ public:
size_t get_tex_coords_offset() const { return (size_t)(3 * sizeof(float)); }
unsigned int get_vertices_count() const { return (unsigned int)m_vertices.size(); }
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class Bed3D
{
@@ -84,38 +84,38 @@ private:
std::string m_model_filename;
// Print volume bounding box exteded with axes and model.
BoundingBoxf3 m_extended_bounding_box;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// Print bed polygon
ExPolygon m_contour;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Slightly expanded print bed polygon, for collision detection.
Polygon m_polygon;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_triangles;
GLModel m_gridlines;
#else
GeometryBuffer m_triangles;
GeometryBuffer m_gridlines;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLTexture m_texture;
// temporary texture shown until the main texture has still no levels compressed
GLTexture m_temp_texture;
GLModel m_model;
Vec3d m_model_offset{ Vec3d::Zero() };
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
unsigned int m_vbo_id{ 0 };
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
Axes m_axes;
float m_scale_factor{ 1.0f };
public:
Bed3D() = default;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
~Bed3D() = default;
#else
~Bed3D() { release_VBOs(); }
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Update print bed model from configuration.
// Return true if the bed shape changed, so the calee will update the UI.
@@ -139,31 +139,50 @@ public:
bool contains(const Point& point) const;
Point point_projection(const Point& point) const;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor, bool show_axes, bool show_texture);
+ void render_for_picking(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor);
+#else
void render(GLCanvas3D& canvas, bool bottom, float scale_factor, bool show_axes, bool show_texture);
void render_for_picking(GLCanvas3D& canvas, bool bottom, float scale_factor);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
private:
// Calculate an extended bounding box from axes and current model for visualization purposes.
BoundingBoxf3 calc_extended_bounding_box() const;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void init_triangles();
void init_gridlines();
#else
void calc_triangles(const ExPolygon& poly);
void calc_gridlines(const ExPolygon& poly, const BoundingBox& bed_bbox);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
static std::tuple detect_type(const Pointfs& shape);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_internal(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, float scale_factor,
+ bool show_axes, bool show_texture, bool picking);
+#else
void render_internal(GLCanvas3D& canvas, bool bottom, float scale_factor,
bool show_axes, bool show_texture, bool picking);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_axes();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture);
+#else
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_texture(bool bottom, GLCanvas3D& canvas);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix);
+ void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking);
+#else
void render_model();
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_default(bool bottom, bool picking);
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void release_VBOs();
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
};
} // GUI
diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp
index 2405f39bc..50e488686 100644
--- a/src/slic3r/GUI/3DScene.cpp
+++ b/src/slic3r/GUI/3DScene.cpp
@@ -1,18 +1,21 @@
#include
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
#include
#include
#include
#endif // ENABLE_SMOOTH_NORMALS
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#include "3DScene.hpp"
#include "GLShader.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "BitmapCache.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "Camera.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/ExtrusionEntity.hpp"
@@ -71,7 +74,7 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char
namespace Slic3r {
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
static void smooth_normals_corner(TriangleMesh& mesh, std::vector& normals)
{
@@ -290,7 +293,7 @@ void GLIndexedVertexArray::render(
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
const float GLVolume::SinkingContours::HalfWidth = 0.25f;
@@ -298,10 +301,22 @@ void GLVolume::SinkingContours::render()
{
update();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
+ if (shader == nullptr)
+ return;
+
+ const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix() * Geometry::assemble_transform(m_shift));
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_shift.x(), m_shift.y(), m_shift.z()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_model.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLVolume::SinkingContours::update()
@@ -319,16 +334,16 @@ void GLVolume::SinkingContours::update()
m_model.reset();
GUI::GLModel::Geometry init_data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::EIndexType::UINT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Triangles, GUI::GLModel::Geometry::EVertexLayout::P3 };
init_data.color = ColorRGBA::WHITE();
unsigned int vertices_counter = 0;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
MeshSlicingParams slicing_params;
slicing_params.trafo = m_parent.world_matrix();
const Polygons polygons = union_(slice_mesh(mesh.its, 0.0f, slicing_params));
for (const ExPolygon& expoly : diff_ex(expand(polygons, float(scale_(HalfWidth))), shrink(polygons, float(scale_(HalfWidth))))) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
const std::vector triangulation = triangulate_expolygon_3d(expoly);
init_data.reserve_vertices(init_data.vertices_count() + triangulation.size());
init_data.reserve_indices(init_data.indices_count() + triangulation.size());
@@ -336,7 +351,7 @@ void GLVolume::SinkingContours::update()
init_data.add_vertex((Vec3f)(v.cast() + 0.015f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
++vertices_counter;
if (vertices_counter % 3 == 0)
- init_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
+ init_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
}
m_model.init_from(std::move(init_data));
@@ -360,7 +375,7 @@ void GLVolume::SinkingContours::update()
init_data.entities.emplace_back(entity);
}
m_model.init_from(init_data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
else
m_shift = box.center() - m_old_box.center();
@@ -375,15 +390,27 @@ void GLVolume::NonManifoldEdges::render()
update();
glsafe(::glLineWidth(2.0f));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
+ if (shader == nullptr)
+ return;
+
+ const GUI::Camera& camera = GUI::wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix() * m_parent.world_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(m_parent.world_matrix().data()));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.set_color(complementary(m_parent.render_color));
#else
m_model.set_color(-1, complementary(m_parent.render_color));
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_model.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLVolume::NonManifoldEdges::update()
@@ -403,8 +430,8 @@ void GLVolume::NonManifoldEdges::update()
const std::vector> edges = its_get_open_edges(mesh.its);
if (!edges.empty()) {
GUI::GLModel::Geometry init_data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Lines, GUI::GLModel::Geometry::EVertexLayout::P3, GUI::GLModel::Geometry::index_type(2 * edges.size()) };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ init_data.format = { GUI::GLModel::Geometry::EPrimitiveType::Lines, GUI::GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2 * edges.size());
init_data.reserve_indices(2 * edges.size());
@@ -414,10 +441,7 @@ void GLVolume::NonManifoldEdges::update()
init_data.add_vertex((Vec3f)mesh.its.vertices[edge.first].cast());
init_data.add_vertex((Vec3f)mesh.its.vertices[edge.second].cast());
vertices_count += 2;
- if (init_data.format.index_type == GUI::GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_line((unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1);
- else
- init_data.add_uint_line(vertices_count - 2, vertices_count - 1);
+ init_data.add_line(vertices_count - 2, vertices_count - 1);
}
m_model.init_from(std::move(init_data));
#else
@@ -438,7 +462,7 @@ void GLVolume::NonManifoldEdges::update()
init_data.entities.emplace_back(entity);
m_model.init_from(init_data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
}
@@ -487,9 +511,9 @@ GLVolume::GLVolume(float r, float g, float b, float a)
, force_neutral_color(false)
, force_sinking_contours(false)
, tverts_range(0, size_t(-1))
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
, qverts_range(0, size_t(-1))
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
{
color = { r, g, b, a };
set_render_color(color);
@@ -605,7 +629,7 @@ const BoundingBoxf3& GLVolume::transformed_non_sinking_bounding_box() const
return *m_transformed_non_sinking_bounding_box;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLVolume::set_range(double min_z, double max_z)
{
this->tverts_range.first = 0;
@@ -671,29 +695,40 @@ void GLVolume::set_range(double min_z, double max_z)
}
}
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void GLVolume::render()
{
if (!is_active)
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = GUI::wxGetApp().get_current_shader();
+ if (shader == nullptr)
+ return;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
if (this->is_left_handed())
glFrontFace(GL_CW);
glsafe(::glCullFace(GL_BACK));
- glsafe(::glPushMatrix());
- glsafe(::glMultMatrixd(world_matrix().data()));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glPushMatrix());
+ glsafe(::glMultMatrixd(world_matrix().data()));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (tverts_range == std::make_pair(0, -1))
model.render();
else
model.render(this->tverts_range);
#else
this->indexed_vertex_array.render(this->tverts_range, this->qverts_range);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
- glsafe(::glPopMatrix());
if (this->is_left_handed())
glFrontFace(GL_CCW);
}
@@ -726,7 +761,7 @@ void GLVolume::render_non_manifold_edges()
}
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::vector GLVolumeCollection::load_object(
const ModelObject* model_object,
int obj_idx,
@@ -737,20 +772,20 @@ std::vector GLVolumeCollection::load_object(
int obj_idx,
const std::vector &instance_idxs,
bool opengl_initialized)
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
std::vector volumes_idx;
for (int volume_idx = 0; volume_idx < int(model_object->volumes.size()); ++volume_idx)
for (int instance_idx : instance_idxs)
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx));
#else
volumes_idx.emplace_back(this->GLVolumeCollection::load_object_volume(model_object, obj_idx, volume_idx, instance_idx, opengl_initialized));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return volumes_idx;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
int GLVolumeCollection::load_object_volume(
const ModelObject* model_object,
int obj_idx,
@@ -763,7 +798,7 @@ int GLVolumeCollection::load_object_volume(
int volume_idx,
int instance_idx,
bool opengl_initialized)
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const ModelVolume *model_volume = model_object->volumes[volume_idx];
const int extruder_id = model_volume->extruder_id();
@@ -772,7 +807,7 @@ int GLVolumeCollection::load_object_volume(
this->volumes.emplace_back(new GLVolume());
GLVolume& v = *this->volumes.back();
v.set_color(color_from_model_volume(*model_volume));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
v.model.init_from(mesh, true);
#else
@@ -785,7 +820,7 @@ int GLVolumeCollection::load_object_volume(
v.indexed_vertex_array.load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
v.composite_id = GLVolume::CompositeID(obj_idx, volume_idx, instance_idx);
if (model_volume->is_model_part()) {
// GLVolume will reference a convex hull from model_volume!
@@ -804,7 +839,7 @@ int GLVolumeCollection::load_object_volume(
// Load SLA auxiliary GLVolumes (for support trees or pad).
// This function produces volumes for multiple instances in a single shot,
// as some object specific mesh conversions may be expensive.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLVolumeCollection::load_object_auxiliary(
const SLAPrintObject* print_object,
int obj_idx,
@@ -823,7 +858,7 @@ void GLVolumeCollection::load_object_auxiliary(
// Timestamp of the last change of the milestone
size_t timestamp,
bool opengl_initialized)
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
assert(print_object->is_step_done(milestone));
Transform3d mesh_trafo_inv = print_object->trafo().inverse();
@@ -836,7 +871,7 @@ void GLVolumeCollection::load_object_auxiliary(
const ModelInstance& model_instance = *print_object->model_object()->instances[instance_idx.first];
this->volumes.emplace_back(new GLVolume((milestone == slaposPad) ? GLVolume::SLA_PAD_COLOR : GLVolume::SLA_SUPPORT_COLOR));
GLVolume& v = *this->volumes.back();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
v.model.init_from(mesh, true);
#else
@@ -850,7 +885,7 @@ void GLVolumeCollection::load_object_auxiliary(
v.indexed_vertex_array.load_mesh(mesh);
#endif // ENABLE_SMOOTH_NORMALS
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
v.composite_id = GLVolume::CompositeID(obj_idx, -int(milestone), (int)instance_idx.first);
v.geometry_id = std::pair(timestamp, model_instance.id().id);
// Create a copy of the convex hull mesh for each instance. Use a move operator on the last instance.
@@ -866,7 +901,7 @@ void GLVolumeCollection::load_object_auxiliary(
}
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
int GLVolumeCollection::load_wipe_tower_preview(
float pos_x, float pos_y, float width, float depth, float height,
@@ -886,7 +921,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
int obj_idx, float pos_x, float pos_y, float width, float depth, float height,
float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized)
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (depth < 0.01f)
return int(this->volumes.size() - 1);
@@ -943,16 +978,16 @@ int GLVolumeCollection::load_wipe_tower_preview(
volumes.emplace_back(new GLVolume(color));
GLVolume& v = *volumes.back();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
v.model.init_from(mesh);
v.model.set_color(color);
#else
v.indexed_vertex_array.load_mesh(mesh);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
v.set_convex_hull(mesh.convex_hull_3d());
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
v.indexed_vertex_array.finalize_geometry(opengl_initialized);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
v.set_volume_offset(Vec3d(pos_x, pos_y, 0.0));
v.set_volume_rotation(Vec3d(0., 0., (M_PI / 180.) * rotation_angle));
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
@@ -967,7 +1002,7 @@ int GLVolumeCollection::load_wipe_tower_preview(
return int(volumes.size() - 1);
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume* GLVolumeCollection::new_toolpath_volume(const ColorRGBA& rgba)
{
GLVolume* out = new_nontoolpath_volume(rgba);
@@ -999,7 +1034,7 @@ GLVolume* GLVolumeCollection::new_nontoolpath_volume(const ColorRGBA& rgba, size
this->volumes.emplace_back(out);
return out;
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCollection::ERenderType type, const Transform3d& view_matrix, std::function filter_func)
{
@@ -1034,7 +1069,12 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
return list;
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
+ std::function filter_func) const
+#else
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func) const
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
if (to_render.empty())
@@ -1044,10 +1084,16 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
if (shader == nullptr)
return;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat_attr");
+ GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat_attr");
+ assert(boost::algorithm::iends_with(shader->get_name(), "_attr"));
+#else
GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat");
GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (type == ERenderType::Transparent) {
glsafe(::glEnable(GL_BLEND));
@@ -1062,36 +1108,34 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
volume.first->set_render_color(true);
// render sinking contours of non-hovered volumes
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
if (sink_shader != nullptr) {
sink_shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
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) {
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
volume.first->render_sinking_contours();
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
shader->start_using();
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
sink_shader->stop_using();
}
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
- glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
- glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
- if (!volume.first->model.is_initialized())
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
- 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);
shader->set_uniform("print_volume.type", static_cast(m_print_volume.type));
@@ -1111,9 +1155,17 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
#endif // ENABLE_ENVIRONMENT_MAP
glcheck();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.first->model.set_color(volume.first->render_color);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#else
+ shader->set_uniform("uniform_color", volume.first->render_color);
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d matrix = view_matrix * volume.first->world_matrix();
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", projection_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
volume.first->render();
#if ENABLE_ENVIRONMENT_MAP
@@ -1124,54 +1176,56 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
if (m_show_sinking_contours) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
if (sink_shader != nullptr) {
sink_shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
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)) {
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDepthFunc(GL_ALWAYS));
volume.first->render_sinking_contours();
glsafe(::glDepthFunc(GL_LESS));
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
shader->start_using();
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
sink_shader->start_using();
}
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#if ENABLE_SHOW_NON_MANIFOLD_EDGES
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
if (edges_shader != nullptr) {
edges_shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (m_show_non_manifold_edges && GUI::wxGetApp().app_config->get("non_manifold_edges") == "1") {
for (GLVolumeWithIdAndZ& volume : to_render) {
volume.first->render_non_manifold_edges();
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
edges_shader->stop_using();
}
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
if (disable_cullface)
@@ -1349,7 +1403,7 @@ std::string GLVolumeCollection::log_memory_info() const
return " (GLVolumeCollection RAM: " + format_memsize_MB(this->cpu_memory_used()) + " GPU: " + format_memsize_MB(this->gpu_memory_used()) + " Both: " + format_memsize_MB(this->gpu_memory_used()) + ")";
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
static void thick_lines_to_geometry(
const Lines& lines,
const std::vector& widths,
@@ -1425,8 +1479,8 @@ static void thick_lines_to_geometry(
if (!is_first && bottom_z_different) {
// Found a change of the layer thickness -> Add a cap at the end of the previous segment.
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
}
// Share top / bottom vertices if possible.
@@ -1476,13 +1530,13 @@ static void thick_lines_to_geometry(
geometry.add_vertex(Vec3f(a2.x(), a2.y(), middle_z), Vec3f(-xy_right_normal.x(), -xy_right_normal.y(), 0.0f));
if (cross2(v_prev, v) > 0.0) {
// Right turn. Fill in the right turn wedge.
- geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
- geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
+ geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
+ geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
}
else {
// Left turn. Fill in the left turn wedge.
- geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
- geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
+ geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
+ geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
}
}
}
@@ -1504,11 +1558,11 @@ static void thick_lines_to_geometry(
// Replace the left / right vertex indices to point to the start of the loop.
const size_t indices_count = geometry.indices_count();
for (size_t u = indices_count - 24; u < indices_count; ++u) {
- const unsigned int id = geometry.extract_uint_index(u);
+ const unsigned int id = geometry.extract_index(u);
if (id == (unsigned int)idx_prev[Left])
- geometry.set_uint_index(u, (unsigned int)idx_initial[Left]);
+ geometry.set_index(u, (unsigned int)idx_initial[Left]);
else if (id == (unsigned int)idx_prev[Right])
- geometry.set_uint_index(u, (unsigned int)idx_initial[Right]);
+ geometry.set_index(u, (unsigned int)idx_initial[Right]);
}
}
}
@@ -1545,36 +1599,36 @@ static void thick_lines_to_geometry(
if (bottom_z_different && (closed || (!is_first && !is_last))) {
// Found a change of the layer thickness -> Add a cap at the beginning of this segment.
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
}
if (!closed) {
// Terminate open paths with caps.
if (is_first) {
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
}
// We don't use 'else' because both cases are true if we have only one line.
if (is_last) {
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
}
}
// Add quads for a straight hollow tube-like segment.
// bottom-right face
- geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
- geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
+ geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
+ geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
// top-right face
- geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
- geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
+ geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
+ geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
// top-left face
- geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
- geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
+ geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
+ geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
// bottom-left face
- geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
- geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
+ geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
+ geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
}
}
@@ -1714,13 +1768,13 @@ static void thick_lines_to_geometry(
if (is_right_turn) {
// Right turn. Fill in the right turn wedge.
- geometry.add_uint_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
- geometry.add_uint_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
+ geometry.add_triangle(idx_prev[Right], idx_a[Right], idx_prev[Top]);
+ geometry.add_triangle(idx_prev[Right], idx_prev[Bottom], idx_a[Right]);
}
else {
// Left turn. Fill in the left turn wedge.
- geometry.add_uint_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
- geometry.add_uint_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
+ geometry.add_triangle(idx_prev[Left], idx_prev[Top], idx_a[Left]);
+ geometry.add_triangle(idx_prev[Left], idx_a[Left], idx_prev[Bottom]);
}
}
else {
@@ -1739,11 +1793,11 @@ static void thick_lines_to_geometry(
// Replace the left / right vertex indices to point to the start of the loop.
const size_t indices_count = geometry.indices_count();
for (size_t u = indices_count - 24; u < indices_count; ++u) {
- const unsigned int id = geometry.extract_uint_index(u);
+ const unsigned int id = geometry.extract_index(u);
if (id == (unsigned int)idx_prev[Left])
- geometry.set_uint_index(u, (unsigned int)idx_initial[Left]);
+ geometry.set_index(u, (unsigned int)idx_initial[Left]);
else if (id == (unsigned int)idx_prev[Right])
- geometry.set_uint_index(u, (unsigned int)idx_initial[Right]);
+ geometry.set_index(u, (unsigned int)idx_initial[Right]);
}
}
@@ -1782,30 +1836,30 @@ static void thick_lines_to_geometry(
if (!closed) {
// Terminate open paths with caps.
if (i == 0) {
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
- geometry.add_uint_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Right], idx_a[Top]);
+ geometry.add_triangle(idx_a[Bottom], idx_a[Top], idx_a[Left]);
}
// We don't use 'else' because both cases are true if we have only one line.
if (i + 1 == lines.size()) {
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
- geometry.add_uint_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Left], idx_b[Top]);
+ geometry.add_triangle(idx_b[Bottom], idx_b[Top], idx_b[Right]);
}
}
// Add quads for a straight hollow tube-like segment.
// bottom-right face
- geometry.add_uint_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
- geometry.add_uint_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
+ geometry.add_triangle(idx_a[Bottom], idx_b[Bottom], idx_b[Right]);
+ geometry.add_triangle(idx_a[Bottom], idx_b[Right], idx_a[Right]);
// top-right face
- geometry.add_uint_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
- geometry.add_uint_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
+ geometry.add_triangle(idx_a[Right], idx_b[Right], idx_b[Top]);
+ geometry.add_triangle(idx_a[Right], idx_b[Top], idx_a[Top]);
// top-left face
- geometry.add_uint_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
- geometry.add_uint_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
+ geometry.add_triangle(idx_a[Top], idx_b[Top], idx_b[Left]);
+ geometry.add_triangle(idx_a[Top], idx_b[Left], idx_a[Left]);
// bottom-left face
- geometry.add_uint_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
- geometry.add_uint_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
+ geometry.add_triangle(idx_a[Left], idx_b[Left], idx_b[Bottom]);
+ geometry.add_triangle(idx_a[Left], idx_b[Bottom], idx_a[Bottom]);
}
}
#else
@@ -2318,9 +2372,9 @@ static void point_to_indexed_vertex_array(const Vec3crd& point,
volume.push_triangle(idxs[3], idxs[1], idxs[4]);
volume.push_triangle(idxs[0], idxs[3], idxs[4]);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::thick_lines_to_verts(
const Lines& lines,
const std::vector& widths,
@@ -2383,10 +2437,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, flo
{
extrusionentity_to_verts(extrusion_path.polyline, extrusion_path.width, extrusion_path.height, print_z, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Fill in the qverts and tverts with quads and triangles for the extrusion_path.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry)
{
Polyline polyline = extrusion_path.polyline;
@@ -2408,10 +2462,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, flo
std::vector heights(lines.size(), extrusion_path.height);
thick_lines_to_verts(lines, widths, heights, false, print_z, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Fill in the qverts and tverts with quads and triangles for the extrusion_loop.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry)
{
Lines lines;
@@ -2445,10 +2499,10 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionLoop &extrusion_loop, flo
}
thick_lines_to_verts(lines, widths, heights, true, print_z, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Fill in the qverts and tverts with quads and triangles for the extrusion_multi_path.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath& extrusion_multi_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry)
{
Lines lines;
@@ -2482,9 +2536,9 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionMultiPath &extrusion_mult
}
thick_lines_to_verts(lines, widths, heights, false, print_z, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection& extrusion_entity_collection, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry)
{
for (const ExtrusionEntity* extrusion_entity : extrusion_entity_collection.entities)
@@ -2496,9 +2550,9 @@ void _3DScene::extrusionentity_to_verts(const ExtrusionEntityCollection &extrusi
for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities)
extrusionentity_to_verts(extrusion_entity, print_z, copy, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void _3DScene::extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry)
{
if (extrusion_entity != nullptr) {
@@ -2563,6 +2617,6 @@ void _3DScene::point3_to_verts(const Vec3crd& point, double width, double height
{
thick_point_to_verts(point, width, height, volume);
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace Slic3r
diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp
index ed2aa804e..950d447f0 100644
--- a/src/slic3r/GUI/3DScene.hpp
+++ b/src/slic3r/GUI/3DScene.hpp
@@ -46,7 +46,7 @@ enum ModelInstanceEPrintVolumeState : unsigned char;
// Return appropriate color based on the ModelVolume.
extern ColorRGBA color_from_model_volume(const ModelVolume& model_volume);
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
// A container for interleaved arrays of 3D vertices and normals,
// possibly indexed by triangles and / or quads.
class GLIndexedVertexArray {
@@ -247,7 +247,7 @@ public:
private:
BoundingBox m_bounding_box;
};
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class GLVolume {
public:
@@ -390,17 +390,17 @@ public:
// Is mouse or rectangle selection over this object to select/deselect it ?
EHoverState hover;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GUI::GLModel model;
#else
// Interleaved triangles & normals with indexed triangles & quads.
GLIndexedVertexArray indexed_vertex_array;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Ranges of triangle and quad indices to be rendered.
std::pair tverts_range;
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
std::pair qverts_range;
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// If the qverts or tverts contain thick extrusions, then offsets keeps pointers of the starts
// of the extrusions per layer.
@@ -410,7 +410,7 @@ public:
// Bounding box of this volume, in unscaled coordinates.
BoundingBoxf3 bounding_box() const {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
return this->model.get_bounding_box();
#else
BoundingBoxf3 out;
@@ -420,7 +420,7 @@ public:
out.defined = true;
}
return out;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void set_color(const ColorRGBA& rgba) { color = rgba; }
@@ -510,20 +510,20 @@ public:
// convex hull
const TriangleMesh* convex_hull() const { return m_convex_hull.get(); }
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool empty() const { return this->model.is_empty(); }
#else
bool empty() const { return this->indexed_vertex_array.empty(); }
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void set_range(double low, double high);
void render();
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void finalize_geometry(bool opengl_initialized) { this->indexed_vertex_array.finalize_geometry(opengl_initialized); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); }
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void set_bounding_boxes_as_dirty() {
m_transformed_bounding_box.reset();
@@ -543,7 +543,7 @@ public:
// Return an estimate of the memory consumed by this class.
size_t cpu_memory_used() const {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
return sizeof(*this) + this->model.cpu_memory_used() + this->print_zs.capacity() * sizeof(coordf_t) +
this->offsets.capacity() * sizeof(size_t);
}
@@ -555,7 +555,7 @@ public:
}
// Return an estimate of the memory held by GPU vertex buffers.
size_t gpu_memory_used() const { return this->indexed_vertex_array.gpu_memory_used(); }
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
size_t total_memory_used() const { return this->cpu_memory_used() + this->gpu_memory_used(); }
};
@@ -615,7 +615,7 @@ public:
GLVolumeCollection() { set_default_slope_normal_z(); }
~GLVolumeCollection() { clear(); }
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::vector load_object(
const ModelObject* model_object,
int obj_idx,
@@ -676,20 +676,25 @@ public:
int load_wipe_tower_preview(
int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized);
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume* new_toolpath_volume(const ColorRGBA& rgba);
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba);
#else
GLVolume* new_toolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
GLVolume* new_nontoolpath_volume(const ColorRGBA& rgba, size_t reserve_vbo_floats = 0);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Render the volumes by OpenGL.
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix,
+ std::function filter_func = std::function()) const;
+#else
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, std::function filter_func = std::function()) const;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
// Finalize the initialization of the geometry & indices,
// upload the geometry and indices to OpenGL VBO objects
// and shrink the allocated data, possibly relasing it if it has been loaded into the VBOs.
@@ -697,7 +702,7 @@ public:
// Release the geometry data assigned to the volumes.
// If OpenGL VBOs were allocated, an OpenGL context has to be active to release them.
void release_geometry() { for (auto *v : volumes) v->release_geometry(); }
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// Clear the geometry
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
@@ -747,7 +752,7 @@ GLVolumeWithIdAndZList volumes_to_render(const GLVolumePtrs& volumes, GLVolumeCo
struct _3DScene
{
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
static void thick_lines_to_verts(const Lines& lines, const std::vector& widths, const std::vector& heights, bool closed, double top_z, GUI::GLModel::Geometry& geometry);
static void thick_lines_to_verts(const Lines3& lines, const std::vector& widths, const std::vector& heights, bool closed, GUI::GLModel::Geometry& geometry);
static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GUI::GLModel::Geometry& geometry);
@@ -767,7 +772,7 @@ struct _3DScene
static void extrusionentity_to_verts(const ExtrusionEntity* extrusion_entity, float print_z, const Point& copy, GLVolume& volume);
static void polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume);
static void point3_to_verts(const Vec3crd& point, double width, double height, GLVolume& volume);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
}
diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp
index b5201d861..d2f0e89aa 100644
--- a/src/slic3r/GUI/DoubleSlider.cpp
+++ b/src/slic3r/GUI/DoubleSlider.cpp
@@ -122,6 +122,10 @@ Control::Control( wxWindow *parent,
this->Bind(wxEVT_KEY_UP, &Control::OnKeyUp, this);
this->Bind(wxEVT_RIGHT_DOWN, &Control::OnRightDown,this);
this->Bind(wxEVT_RIGHT_UP, &Control::OnRightUp, this);
+ this->Bind(wxEVT_SIZE, [this](wxSizeEvent& event) {
+ m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
+ event.Skip();
+ });
// control's view variables
SLIDER_MARGIN = 4 + GUI::wxGetApp().em_unit();
@@ -137,8 +141,14 @@ Control::Control( wxWindow *parent,
m_line_pens = { &DARK_GREY_PEN, &GREY_PEN, &LIGHT_GREY_PEN };
m_segm_pens = { &DARK_ORANGE_PEN, &ORANGE_PEN, &LIGHT_ORANGE_PEN };
+ FOCUS_RECT_PEN = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
+ FOCUS_RECT_BRUSH = wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT);
+
m_font = GetFont();
this->SetMinSize(get_min_size());
+
+ if (style == wxSL_VERTICAL)
+ m_ruler.set_parent(this->GetParent());
}
void Control::msw_rescale()
@@ -170,6 +180,9 @@ void Control::msw_rescale()
SetMinSize(get_min_size());
GetParent()->Layout();
+
+ m_ruler.update_dpi();
+ m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
}
void Control::sys_color_changed()
@@ -266,7 +279,11 @@ void Control::SetMaxValue(const int max_value)
void Control::SetSliderValues(const std::vector& values)
{
m_values = values;
- m_ruler.init(m_values);
+ m_ruler.init(m_values, get_scroll_step());
+
+ // When "No sparce layer" is enabled, use m_layers_values for ruler update.
+ // Because of m_values has duplicate values in this case.
+// m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
}
void Control::draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos)
@@ -426,9 +443,12 @@ void Control::SetLayersTimes(const std::vector& layers_times, float total
if (m_layers_values.size() != m_layers_times.size())
for (size_t i = m_layers_times.size(); i < m_layers_values.size(); i++)
m_layers_times.push_back(total_time);
+ m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
Refresh();
Update();
}
+ else
+ m_ruler.update(m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
}
void Control::SetLayersTimes(const std::vector& layers_times)
@@ -494,15 +514,17 @@ void Control::get_lower_and_higher_position(int& lower_pos, int& higher_pos)
}
}
-void Control::draw_focus_rect()
+void Control::draw_focus_rect(wxDC& dc)
{
if (!m_is_focused)
return;
const wxSize sz = GetSize();
- wxPaintDC dc(this);
- const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
- dc.SetPen(pen);
- dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT));
+// wxPaintDC dc(this);
+ //const wxPen pen = wxPen(wxColour(128, 128, 10), 1, wxPENSTYLE_DOT);
+ //dc.SetPen(pen);
+ //dc.SetBrush(wxBrush(wxColour(0, 0, 0), wxBRUSHSTYLE_TRANSPARENT));
+ dc.SetPen(FOCUS_RECT_PEN);
+ dc.SetBrush(FOCUS_RECT_BRUSH);
dc.DrawRectangle(1, 1, sz.x - 2, sz.y - 2);
}
@@ -513,11 +535,12 @@ void Control::render()
#else
SetBackgroundColour(GetParent()->GetBackgroundColour());
#endif // _WIN32
- draw_focus_rect();
wxPaintDC dc(this);
dc.SetFont(m_font);
+ draw_focus_rect(dc);
+
const wxCoord lower_pos = get_position_from_value(m_lower_value);
const wxCoord higher_pos = get_position_from_value(m_higher_value);
@@ -807,7 +830,7 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType l
}
wxColour old_clr = dc.GetTextForeground();
- const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : wxPen(old_clr);
+ const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : /*wxPen(old_clr)*/GREY_PEN;
dc.SetPen(pen);
dc.SetTextForeground(pen.GetColour());
@@ -1028,8 +1051,10 @@ void Control::draw_colored_band(wxDC& dc)
}
}
-void Control::Ruler::init(const std::vector& values)
+void Control::Ruler::init(const std::vector& values, double scroll_step)
{
+ if (!m_parent)
+ return;
max_values.clear();
max_values.reserve(std::count(values.begin(), values.end(), values.front()));
@@ -1039,14 +1064,35 @@ void Control::Ruler::init(const std::vector& values)
it = std::find(it + 1, values.end(), values.front());
}
max_values.push_back(*(it - 1));
+
+ update(values, scroll_step);
}
-void Control::Ruler::update(wxWindow* win, const std::vector& values, double scroll_step)
+void Control::Ruler::set_parent(wxWindow* parent)
{
- if (values.empty())
+ m_parent = parent;
+ update_dpi();
+}
+
+void Control::Ruler::update_dpi()
+{
+ if (m_parent)
+ m_DPI = GUI::get_dpi_for_window(m_parent);
+}
+
+void Control::Ruler::update(const std::vector& values, double scroll_step)
+{
+ if (!m_parent || values.empty() ||
+ // check if need to update ruler in respect to input values
+ values.front() == m_min_val && values.back() == m_max_val && m_scroll_step == scroll_step && max_values.size() == m_max_values_cnt)
return;
- int DPI = GUI::get_dpi_for_window(win);
- int pixels_per_sm = lround((double)(DPI) * 5.0/25.4);
+
+ m_min_val = values.front();
+ m_max_val = values.back();
+ m_scroll_step = scroll_step;
+ m_max_values_cnt = max_values.size();
+
+ int pixels_per_sm = lround((double)(m_DPI) * 5.0/25.4);
if (lround(scroll_step) > pixels_per_sm) {
long_step = -1.0;
@@ -1091,11 +1137,11 @@ void Control::Ruler::update(wxWindow* win, const std::vector& values, do
void Control::draw_ruler(wxDC& dc)
{
- if (m_values.empty())
+ if (m_values.empty() || !m_ruler.can_draw())
return;
// When "No sparce layer" is enabled, use m_layers_values for ruler update.
// Because of m_values has duplicate values in this case.
- m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
+// m_ruler.update(this->GetParent(), m_layers_values.empty() ? m_values : m_layers_values, get_scroll_step());
int height, width;
get_size(&width, &height);
diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp
index e0f713d87..e4654d604 100644
--- a/src/slic3r/GUI/DoubleSlider.hpp
+++ b/src/slic3r/GUI/DoubleSlider.hpp
@@ -303,7 +303,7 @@ public:
protected:
void render();
- void draw_focus_rect();
+ void draw_focus_rect(wxDC& dc);
void draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end);
void draw_scroll_line(wxDC& dc, const int lower_pos, const int higher_pos);
void draw_thumb(wxDC& dc, const wxCoord& pos_coord, const SelectedSlider& selection);
@@ -438,19 +438,36 @@ private:
wxPen GREY_PEN;
wxPen LIGHT_GREY_PEN;
+ wxPen FOCUS_RECT_PEN;
+ wxBrush FOCUS_RECT_BRUSH;
+
std::vector m_line_pens;
std::vector m_segm_pens;
- struct Ruler {
+ class Ruler {
+ wxWindow* m_parent{nullptr}; // m_parent is nullptr for Unused ruler
+ // in this case we will not init/update/render it
+ // values to check if ruler has to be updated
+ double m_min_val;
+ double m_max_val;
+ double m_scroll_step;
+ size_t m_max_values_cnt;
+ int m_DPI;
+
+ public:
+
double long_step;
double short_step;
std::vector max_values;// max value for each object/instance in sequence print
// > 1 for sequential print
- void init(const std::vector& values);
- void update(wxWindow* win, const std::vector& values, double scroll_step);
+ void set_parent(wxWindow* parent);
+ void update_dpi();
+ void init(const std::vector& values, double scroll_step);
+ void update(const std::vector& values, double scroll_step);
bool is_ok() { return long_step > 0 && short_step > 0; }
size_t count() { return max_values.size(); }
+ bool can_draw() { return m_parent != nullptr; }
} m_ruler;
};
diff --git a/src/slic3r/GUI/DoubleSlider_Utils.hpp b/src/slic3r/GUI/DoubleSlider_Utils.hpp
deleted file mode 100644
index 283d527fa..000000000
--- a/src/slic3r/GUI/DoubleSlider_Utils.hpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef slic3r_GUI_DoubleSlider_Utils_hpp_
-#define slic3r_GUI_DoubleSlider_Utils_hpp_
-
-#include
-#include
-
-
-#endif // slic3r_GUI_DoubleSlider_Utils_hpp_
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index cfe6fe418..cb5437635 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -184,7 +184,11 @@ void GCodeViewer::COG::render()
init();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("toolpaths_cog");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -192,6 +196,18 @@ void GCodeViewer::COG::render()
glsafe(::glDisable(GL_DEPTH_TEST));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ Transform3d matrix = camera.get_view_matrix() * Geometry::assemble_transform(cog());
+ if (m_fixed_size) {
+ const double inv_zoom = wxGetApp().plater()->get_camera().get_inv_zoom();
+ matrix = matrix * Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), inv_zoom * Vec3d::Ones());
+ }
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+ m_model.render();
+#else
glsafe(::glPushMatrix());
const Vec3d position = cog();
glsafe(::glTranslated(position.x(), position.y(), position.z()));
@@ -200,8 +216,8 @@ void GCodeViewer::COG::render()
glsafe(::glScaled(inv_zoom, inv_zoom, inv_zoom));
}
m_model.render();
-
glsafe(::glPopMatrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->stop_using();
@@ -297,11 +313,11 @@ void GCodeViewer::SequentialRangeCap::reset() {
void GCodeViewer::SequentialView::Marker::init()
{
m_model.init_from(stilized_arrow(16, 2.0f, 4.0f, 1.0f, 8.0f));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.set_color({ 1.0f, 1.0f, 1.0f, 0.5f });
#else
m_model.set_color(-1, { 1.0f, 1.0f, 1.0f, 0.5f });
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GCodeViewer::SequentialView::Marker::set_world_position(const Vec3f& position)
@@ -315,7 +331,11 @@ void GCodeViewer::SequentialView::Marker::render()
if (!m_visible)
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -324,13 +344,22 @@ void GCodeViewer::SequentialView::Marker::render()
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
-
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d matrix = camera.get_view_matrix() * m_world_transform.cast();
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixf(m_world_transform.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_model.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
shader->stop_using();
@@ -663,7 +692,11 @@ void GCodeViewer::init()
#if !DISABLE_GCODEVIEWER_INSTANCED_MODELS
if (wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::InstancedModel;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ buffer.shader = "gouraud_light_instanced_attr";
+#else
buffer.shader = "gouraud_light_instanced";
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
buffer.model.model.init_from(diamond(16));
buffer.model.color = option_color(type);
buffer.model.instances.format = InstanceVBuffer::EFormat::InstancedModel;
@@ -672,7 +705,11 @@ void GCodeViewer::init()
#endif // !DISABLE_GCODEVIEWER_INSTANCED_MODELS
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::BatchedModel;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ buffer.shader = "gouraud_light_attr";
+#else
buffer.shader = "gouraud_light";
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
buffer.model.data = diamond(16);
buffer.model.color = option_color(type);
@@ -686,13 +723,22 @@ void GCodeViewer::init()
case EMoveType::Extrude: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Triangle;
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ buffer.shader = "gouraud_light_attr";
+#else
buffer.shader = "gouraud_light";
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
break;
}
case EMoveType::Travel: {
buffer.render_primitive_type = TBuffer::ERenderPrimitiveType::Line;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ buffer.vertices.format = VBuffer::EFormat::Position;
+ buffer.shader = "flat_attr";
+#else
buffer.vertices.format = VBuffer::EFormat::PositionNormal3;
buffer.shader = "toolpaths_lines";
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
break;
}
}
@@ -711,11 +757,11 @@ void GCodeViewer::init()
m_gl_data_initialized = true;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print)
#else
void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized)
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
// avoid processing if called with the same gcode_result
#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC
@@ -754,11 +800,11 @@ void GCodeViewer::load(const GCodeProcessorResult& gcode_result, const Print& pr
m_filament_densities = gcode_result.filament_densities;
if (wxGetApp().is_editor())
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
load_shells(print);
#else
load_shells(print, initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
else {
Pointfs bed_shape;
std::string texture;
@@ -1278,11 +1324,21 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
// format data into the buffers to be rendered as lines
auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
// x component of the normal to the current segment (the normal is parallel to the XY plane)
const Vec3f dir = (curr.position - prev.position).normalized();
Vec3f normal(dir.y(), -dir.x(), 0.0);
normal.normalize();
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto add_vertex = [&vertices](const GCodeProcessorResult::MoveVertex& vertex) {
+ // add position
+ vertices.push_back(vertex.position.x());
+ vertices.push_back(vertex.position.y());
+ vertices.push_back(vertex.position.z());
+ };
+#else
auto add_vertex = [&vertices, &normal](const GCodeProcessorResult::MoveVertex& vertex) {
// add position
vertices.push_back(vertex.position.x());
@@ -1293,6 +1349,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
vertices.push_back(normal.y());
vertices.push_back(normal.z());
};
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// add previous vertex
add_vertex(prev);
@@ -1571,7 +1628,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
const Transform3d trafo = Geometry::assemble_transform((curr.position - 0.5f * curr.height * Vec3f::UnitZ()).cast(), Vec3d::Zero(), { width, width, height });
const Eigen::Matrix normal_matrix = trafo.matrix().template block<3, 3>(0, 0).inverse().transpose();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// append vertices
const size_t vertices_count = data.vertices_count();
for (size_t i = 0; i < vertices_count; ++i) {
@@ -1604,7 +1661,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
vertices.push_back(static_cast(normal.z()));
}
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// append instance position
instances.push_back(curr.position.x());
@@ -1615,10 +1672,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
};
auto add_indices_as_model_batch = [](const GLModel::Geometry& data, IndexBuffer& indices, IBufferType base_index) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
const size_t indices_count = data.indices_count();
for (size_t i = 0; i < indices_count; ++i) {
- indices.push_back(static_cast(data.extract_ushort_index(i) + base_index));
+ indices.push_back(static_cast(data.extract_index(i) + base_index));
}
#else
for (const auto& entity : data.entities) {
@@ -1626,7 +1683,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
indices.push_back(static_cast(entity.indices[i] + base_index));
}
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -2297,11 +2354,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
progress_dialog->Destroy();
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GCodeViewer::load_shells(const Print& print)
#else
void GCodeViewer::load_shells(const Print& print, bool initialized)
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (print.objects().empty())
// no shells, return
@@ -2318,11 +2375,11 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
}
size_t current_volumes_count = m_shells.volumes.volumes.size();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_shells.volumes.load_object(model_obj, object_id, instance_ids);
#else
m_shells.volumes.load_object(model_obj, object_id, instance_ids, initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// adjust shells' z if raft is present
const SlicingParameters& slicing_parameters = obj->slicing_parameters();
@@ -2346,7 +2403,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
const float depth = print.wipe_tower_data(extruders_count).depth;
const float brim_width = print.wipe_tower_data(extruders_count).brim_width;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
m_shells.volumes.load_wipe_tower_preview(config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
!print.is_step_done(psWipeTower), brim_width);
@@ -2362,7 +2419,7 @@ void GCodeViewer::load_shells(const Print& print, bool initialized)
m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle,
!print.is_step_done(psWipeTower), brim_width, initialized);
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
@@ -2912,15 +2969,17 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
void GCodeViewer::render_toolpaths()
{
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
- float point_size = 20.0f;
+ const float point_size = 20.0f;
#else
- float point_size = 0.8f;
+ const float point_size = 0.8f;
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
- std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ const std::array light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
const Camera& camera = wxGetApp().plater()->get_camera();
- double zoom = camera.get_zoom();
+ const double zoom = camera.get_zoom();
const std::array& viewport = camera.get_viewport();
- float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
+ const float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast(viewport[3]) / (2.0f * static_cast(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
static_cast(viewport[3]) * 0.0005;
auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) {
@@ -2960,9 +3019,11 @@ void GCodeViewer::render_toolpaths()
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
};
- auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
shader.set_uniform("light_intensity", light_intensity);
};
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
auto render_as_lines = [
#if ENABLE_GCODE_VIEWER_STATISTICS
this
@@ -3013,11 +3074,11 @@ void GCodeViewer::render_toolpaths()
}
if (range.vbo > 0) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
buffer.model.model.set_color(range.color);
#else
buffer.model.model.set_color(-1, range.color);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
buffer.model.model.render_instanced(range.vbo, range.count);
#if ENABLE_GCODE_VIEWER_STATISTICS
++m_statistics.gl_instanced_models_calls_count;
@@ -3027,11 +3088,19 @@ void GCodeViewer::render_toolpaths()
}
};
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GCODE_VIEWER_STATISTICS
+ auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
+#else
+ auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader, int position_id, int normal_id) {
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+#else
#if ENABLE_GCODE_VIEWER_STATISTICS
auto render_as_batched_model = [this](TBuffer& buffer, GLShaderProgram& shader) {
#else
auto render_as_batched_model = [](TBuffer& buffer, GLShaderProgram& shader) {
#endif // ENABLE_GCODE_VIEWER_STATISTICS
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
struct Range
{
@@ -3040,30 +3109,44 @@ void GCodeViewer::render_toolpaths()
bool intersects(const Range& other) const { return (other.last < first || other.first > last) ? false : true; }
};
Range buffer_range = { 0, 0 };
- size_t indices_per_instance = buffer.model.data.indices_count();
+ const size_t indices_per_instance = buffer.model.data.indices_count();
for (size_t j = 0; j < buffer.indices.size(); ++j) {
const IBuffer& i_buffer = buffer.indices[j];
buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance;
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (position_id != -1) {
+ glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(position_id));
+ }
+#else
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
- bool has_normals = buffer.vertices.normal_size_floats() > 0;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ const bool has_normals = buffer.vertices.normal_size_floats() > 0;
if (has_normals) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1) {
+ glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(normal_id));
+ }
+#else
glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
for (auto& range : buffer.model.instances.render_ranges.ranges) {
- Range range_range = { range.offset, range.offset + range.count };
+ const Range range_range = { range.offset, range.offset + range.count };
if (range_range.intersects(buffer_range)) {
shader.set_uniform("uniform_color", range.color);
- unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0;
- size_t offset_bytes = static_cast(offset) * indices_per_instance * sizeof(IBufferType);
- Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) };
- size_t count = static_cast(render_range.last - render_range.first) * indices_per_instance;
+ const unsigned int offset = (range_range.first > buffer_range.first) ? range_range.first - buffer_range.first : 0;
+ const size_t offset_bytes = static_cast(offset) * indices_per_instance * sizeof(IBufferType);
+ const Range render_range = { std::max(range_range.first, buffer_range.first), std::min(range_range.last, buffer_range.last) };
+ const size_t count = static_cast(render_range.last - render_range.first) * indices_per_instance;
if (count > 0) {
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)count, GL_UNSIGNED_SHORT, (const void*)offset_bytes));
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -3075,10 +3158,17 @@ void GCodeViewer::render_toolpaths()
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1)
+ glsafe(::glDisableVertexAttribArray(normal_id));
+ if (position_id != -1)
+ glsafe(::glDisableVertexAttribArray(position_id));
+#else
if (has_normals)
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
buffer_range.first = buffer_range.last;
@@ -3089,8 +3179,8 @@ void GCodeViewer::render_toolpaths()
return (zoom < 5.0) ? 1.0 : (1.0 + 5.0 * (zoom - 5.0) / (100.0 - 5.0));
};
- unsigned char begin_id = buffer_id(EMoveType::Retract);
- unsigned char end_id = buffer_id(EMoveType::Count);
+ const unsigned char begin_id = buffer_id(EMoveType::Retract);
+ const unsigned char end_id = buffer_id(EMoveType::Count);
for (unsigned char i = begin_id; i < end_id; ++i) {
TBuffer& buffer = m_buffers[i];
@@ -3098,77 +3188,121 @@ void GCodeViewer::render_toolpaths()
continue;
GLShaderProgram* shader = wxGetApp().get_shader(buffer.shader.c_str());
- if (shader != nullptr) {
- shader->start_using();
+ if (shader == nullptr)
+ continue;
- if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
- shader->set_uniform("emission_factor", 0.25f);
- render_as_instanced_model(buffer, *shader);
- shader->set_uniform("emission_factor", 0.0f);
- }
- else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
- shader->set_uniform("emission_factor", 0.25f);
- render_as_batched_model(buffer, *shader);
- shader->set_uniform("emission_factor", 0.0f);
- }
- else {
- switch (buffer.render_primitive_type) {
- case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
- case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break;
- default: break;
- }
- int uniform_color = shader->get_uniform_location("uniform_color");
- auto it_path = buffer.render_paths.begin();
- for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast(buffer.indices.size()); ++ibuffer_id) {
- const IBuffer& i_buffer = buffer.indices[ibuffer_id];
- // Skip all paths with ibuffer_id < ibuffer_id.
- for (; it_path != buffer.render_paths.end() && it_path->ibuffer_id < ibuffer_id; ++ it_path) ;
- if (it_path == buffer.render_paths.end() || it_path->ibuffer_id > ibuffer_id)
- // Not found. This shall not happen.
- continue;
+ shader->start_using();
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
- glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
- glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
- bool has_normals = buffer.vertices.normal_size_floats() > 0;
- if (has_normals) {
- glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
- glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
- }
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ int position_id = -1;
+ int normal_id = -1;
+ const Transform3d& view_matrix = camera.get_view_matrix();
+ shader->set_uniform("view_model_matrix", view_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
+ position_id = shader->get_attrib_location("v_position");
+ normal_id = shader->get_attrib_location("v_normal");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
- // Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors.
- switch (buffer.render_primitive_type)
- {
- case TBuffer::ERenderPrimitiveType::Point: {
- render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color);
- break;
- }
- case TBuffer::ERenderPrimitiveType::Line: {
- glsafe(::glLineWidth(static_cast(line_width(zoom))));
- render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color);
- break;
- }
- case TBuffer::ERenderPrimitiveType::Triangle: {
- render_as_triangles(it_path, buffer.render_paths.end(), *shader, uniform_color);
- break;
- }
- default: { break; }
- }
-
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
-
- if (has_normals)
- glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
-
- glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
- }
- }
-
- shader->stop_using();
+ if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
+ shader->set_uniform("emission_factor", 0.25f);
+ render_as_instanced_model(buffer, *shader);
+ shader->set_uniform("emission_factor", 0.0f);
}
+ else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
+ shader->set_uniform("emission_factor", 0.25f);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_as_batched_model(buffer, *shader, position_id, normal_id);
+#else
+ render_as_batched_model(buffer, *shader);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("emission_factor", 0.0f);
+ }
+ else {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point)
+ shader_init_as_points(*shader);
+#else
+ switch (buffer.render_primitive_type) {
+ case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
+ case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break;
+ default: break;
+ }
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ const int uniform_color = shader->get_uniform_location("uniform_color");
+
+ auto it_path = buffer.render_paths.begin();
+ for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast(buffer.indices.size()); ++ibuffer_id) {
+ const IBuffer& i_buffer = buffer.indices[ibuffer_id];
+ // Skip all paths with ibuffer_id < ibuffer_id.
+ for (; it_path != buffer.render_paths.end() && it_path->ibuffer_id < ibuffer_id; ++it_path);
+ if (it_path == buffer.render_paths.end() || it_path->ibuffer_id > ibuffer_id)
+ // Not found. This shall not happen.
+ continue;
+
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (position_id != -1) {
+ glsafe(::glVertexAttribPointer(position_id, buffer.vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(position_id));
+ }
+#else
+ glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ const bool has_normals = buffer.vertices.normal_size_floats() > 0;
+ if (has_normals) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1) {
+ glsafe(::glVertexAttribPointer(normal_id, buffer.vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(normal_id));
+ }
+#else
+ glsafe(::glNormalPointer(GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.normal_offset_bytes()));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ }
+
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
+
+ // Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors.
+ switch (buffer.render_primitive_type)
+ {
+ case TBuffer::ERenderPrimitiveType::Point: {
+ render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color);
+ break;
+ }
+ case TBuffer::ERenderPrimitiveType::Line: {
+ glsafe(::glLineWidth(static_cast(line_width(zoom))));
+ render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color);
+ break;
+ }
+ case TBuffer::ERenderPrimitiveType::Triangle: {
+ render_as_triangles(it_path, buffer.render_paths.end(), *shader, uniform_color);
+ break;
+ }
+ default: { break; }
+ }
+
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1)
+ glsafe(::glDisableVertexAttribArray(normal_id));
+ if (position_id != -1)
+ glsafe(::glDisableVertexAttribArray(position_id));
+#else
+ if (has_normals)
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
+
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+ }
+ }
+
+ shader->stop_using();
}
#if ENABLE_GCODE_VIEWER_STATISTICS
@@ -3177,37 +3311,74 @@ void GCodeViewer::render_toolpaths()
auto render_sequential_range_cap = []
#endif // ENABLE_GCODE_VIEWER_STATISTICS
(const SequentialRangeCap& cap) {
- GLShaderProgram* shader = wxGetApp().get_shader(cap.buffer->shader.c_str());
- if (shader != nullptr) {
- shader->start_using();
+ const TBuffer* buffer = cap.buffer;
+ GLShaderProgram* shader = wxGetApp().get_shader(buffer->shader.c_str());
+ if (shader == nullptr)
+ return;
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
- glsafe(::glVertexPointer(cap.buffer->vertices.position_size_floats(), GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.position_offset_bytes()));
- glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
- bool has_normals = cap.buffer->vertices.normal_size_floats() > 0;
- if (has_normals) {
- glsafe(::glNormalPointer(GL_FLOAT, cap.buffer->vertices.vertex_size_bytes(), (const void*)cap.buffer->vertices.normal_offset_bytes()));
- glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+ shader->start_using();
+
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ int position_id = -1;
+ int normal_id = -1;
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d& view_matrix = camera.get_view_matrix();
+ shader->set_uniform("view_model_matrix", view_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+
+ position_id = shader->get_attrib_location("v_position");
+ normal_id = shader->get_attrib_location("v_normal");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (position_id != -1) {
+ glsafe(::glVertexAttribPointer(position_id, buffer->vertices.position_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(position_id));
+ }
+#else
+ glsafe(::glVertexPointer(buffer->vertices.position_size_floats(), GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.position_offset_bytes()));
+ glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ const bool has_normals = buffer->vertices.normal_size_floats() > 0;
+ if (has_normals) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1) {
+ glsafe(::glVertexAttribPointer(normal_id, buffer->vertices.normal_size_floats(), GL_FLOAT, GL_FALSE, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes()));
+ glsafe(::glEnableVertexAttribArray(normal_id));
}
+#else
+ glsafe(::glNormalPointer(GL_FLOAT, buffer->vertices.vertex_size_bytes(), (const void*)buffer->vertices.normal_offset_bytes()));
+ glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ }
- shader->set_uniform("uniform_color", cap.color);
+ shader->set_uniform("uniform_color", cap.color);
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo));
- glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)cap.indices_count(), GL_UNSIGNED_SHORT, nullptr));
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cap.ibo));
+ glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)cap.indices_count(), GL_UNSIGNED_SHORT, nullptr));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
#if ENABLE_GCODE_VIEWER_STATISTICS
- ++m_statistics.gl_triangles_calls_count;
+ ++m_statistics.gl_triangles_calls_count;
#endif // ENABLE_GCODE_VIEWER_STATISTICS
- if (has_normals)
- glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (normal_id != -1)
+ glsafe(::glDisableVertexAttribArray(normal_id));
+ if (position_id != -1)
+ glsafe(::glDisableVertexAttribArray(position_id));
+#else
+ if (has_normals)
+ glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
- glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+ glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
- shader->stop_using();
- }
+ glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+
+ shader->stop_using();
};
for (unsigned int i = 0; i < 2; ++i) {
@@ -3221,11 +3392,15 @@ void GCodeViewer::render_shells()
if (!m_shells.visible || m_shells.volumes.empty())
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
// when the background processing is enabled, it may happen that the shells data have been loaded
// before opengl has been initialized for the preview canvas.
// when this happens, the volumes' data have not been sent to gpu yet.
@@ -3233,12 +3408,17 @@ void GCodeViewer::render_shells()
if (!v->indexed_vertex_array.has_VBOs())
v->finalize_geometry(true);
}
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
// glsafe(::glDepthMask(GL_FALSE));
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, camera.get_view_matrix(), camera.get_projection_matrix());
+#else
m_shells.volumes.render(GLVolumeCollection::ERenderType::Transparent, true, wxGetApp().plater()->get_camera().get_view_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->stop_using();
// glsafe(::glDepthMask(GL_TRUE));
@@ -4449,14 +4629,14 @@ void GCodeViewer::render_statistics()
ImGuiWrapper& imgui = *wxGetApp().imgui();
- auto add_time = [this, &imgui](const std::string& label, int64_t time) {
+ auto add_time = [&imgui](const std::string& label, int64_t time) {
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
ImGui::SameLine(offset);
imgui.text(std::to_string(time) + " ms (" + get_time_dhms(static_cast(time) * 0.001f) + ")");
};
- auto add_memory = [this, &imgui](const std::string& label, int64_t memory) {
- auto format_string = [memory](const std::string& units, float value) {
+ auto add_memory = [&imgui](const std::string& label, int64_t memory) {
+ auto format_string = [memory](const std::string& units, float value) {
return std::to_string(memory) + " bytes (" +
Slic3r::float_to_string_decimal_point(float(memory) * value, 3)
+ " " + units + ")";
@@ -4478,7 +4658,7 @@ void GCodeViewer::render_statistics()
imgui.text(format_string("GB", inv_gb));
};
- auto add_counter = [this, &imgui](const std::string& label, int64_t counter) {
+ auto add_counter = [&imgui](const std::string& label, int64_t counter) {
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
ImGui::SameLine(offset);
imgui.text(std::to_string(counter));
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index bdb3ed983..438fc55fd 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -365,11 +365,11 @@ class GCodeViewer
}
case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); }
case ERenderPrimitiveType::BatchedModel: {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
return !model.data.vertices.empty() && !model.data.indices.empty() &&
#else
return model.data.vertices_count() > 0 && model.data.indices_count() &&
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
!vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
}
default: { return false; }
@@ -421,11 +421,11 @@ class GCodeViewer
const float radius = m_fixed_size ? 10.0f : 1.0f;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.init_from(smooth_sphere(32, radius));
#else
m_model.init_from(its_make_sphere(radius, PI / 32.0));
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
};
#endif // ENABLE_SHOW_TOOLPATHS_COG
@@ -823,11 +823,11 @@ public:
void init();
// extract rendering data from the given parameters
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void load(const GCodeProcessorResult& gcode_result, const Print& print);
#else
void load(const GCodeProcessorResult& gcode_result, const Print& print, bool initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// recalculate ranges in dependence of what is visible and sets tool/print colors
void refresh(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors);
#if ENABLE_PREVIEW_LAYOUT
@@ -887,11 +887,11 @@ public:
private:
void load_toolpaths(const GCodeProcessorResult& gcode_result);
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void load_shells(const Print& print);
#else
void load_shells(const Print& print, bool initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if !ENABLE_PREVIEW_LAYOUT
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
#endif // !ENABLE_PREVIEW_LAYOUT
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index cd80dd1a5..76bcde947 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -14,19 +14,16 @@
#include "libslic3r/Technologies.hpp"
#include "libslic3r/Tesselate.hpp"
#include "libslic3r/PresetBundle.hpp"
-#include "slic3r/GUI/3DBed.hpp"
-#include "slic3r/GUI/3DScene.hpp"
-#include "slic3r/GUI/BackgroundSlicingProcess.hpp"
-#include "slic3r/GUI/GLShader.hpp"
-#include "slic3r/GUI/GUI.hpp"
-#include "slic3r/GUI/Tab.hpp"
-#include "slic3r/GUI/GUI_Preview.hpp"
-#include "slic3r/GUI/OpenGLManager.hpp"
-#include "slic3r/GUI/Plater.hpp"
-#include "slic3r/GUI/MainFrame.hpp"
-#include "slic3r/Utils/UndoRedo.hpp"
-#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
-
+#include "3DBed.hpp"
+#include "3DScene.hpp"
+#include "BackgroundSlicingProcess.hpp"
+#include "GLShader.hpp"
+#include "GUI.hpp"
+#include "Tab.hpp"
+#include "GUI_Preview.hpp"
+#include "OpenGLManager.hpp"
+#include "Plater.hpp"
+#include "MainFrame.hpp"
#include "GUI_App.hpp"
#include "GUI_ObjectList.hpp"
#include "GUI_ObjectManipulation.hpp"
@@ -35,6 +32,9 @@
#include "NotificationManager.hpp"
#include "format.hpp"
+#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
+#include "slic3r/Utils/UndoRedo.hpp"
+
#if ENABLE_RETINA_GL
#include "slic3r/Utils/RetinaHelper.hpp"
#endif
@@ -72,7 +72,7 @@
static constexpr const float TRACKBALLSIZE = 0.8f;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
static const Slic3r::ColorRGBA DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f, 1.0f };
static const Slic3r::ColorRGBA DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f, 1.0f };
static const Slic3r::ColorRGBA ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f, 1.0f };
@@ -82,16 +82,16 @@ static const Slic3r::ColorRGB DEFAULT_BG_DARK_COLOR = { 0.478f, 0.478f, 0.478f
static const Slic3r::ColorRGB DEFAULT_BG_LIGHT_COLOR = { 0.753f, 0.753f, 0.753f };
static const Slic3r::ColorRGB ERROR_BG_DARK_COLOR = { 0.478f, 0.192f, 0.039f };
static const Slic3r::ColorRGB ERROR_BG_LIGHT_COLOR = { 0.753f, 0.192f, 0.039f };
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Number of floats
static constexpr const size_t MAX_VERTEX_BUFFER_SIZE = 131072 * 6; // 3.15MB
// Reserve size in number of floats.
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE = 131072 * 2; // 1.05MB
// Reserve size in number of floats, maximum sum of all preallocated buffers.
//static constexpr const size_t VERTEX_BUFFER_RESERVE_SIZE_SUM_MAX = 1024 * 1024 * 128 / 4; // 128MB
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
namespace Slic3r {
namespace GUI {
@@ -161,7 +161,11 @@ void GLCanvas3D::LayersEditing::select_object(const Model &model, int object_id)
bool GLCanvas3D::LayersEditing::is_allowed() const
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ return wxGetApp().get_shader("variable_layer_height_attr") != nullptr && m_z_texture_id > 0;
+#else
return wxGetApp().get_shader("variable_layer_height") != nullptr && m_z_texture_id > 0;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
bool GLCanvas3D::LayersEditing::is_enabled() const
@@ -263,24 +267,29 @@ void GLCanvas3D::LayersEditing::render_overlay(const GLCanvas3D& canvas)
GLCanvas3D::LayersEditing::s_overlay_window_width = ImGui::GetWindowSize().x /*+ (float)m_layers_texture.width/4*/;
imgui.end();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_active_object_annotations(canvas);
+ render_profile(canvas);
+#else
const Rect& bar_rect = get_bar_rect_viewport(canvas);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_profile.dirty = m_profile.old_bar_rect != bar_rect;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
render_active_object_annotations(canvas, bar_rect);
render_profile(bar_rect);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_profile.old_bar_rect = bar_rect;
m_profile.dirty = false;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
float GLCanvas3D::LayersEditing::get_cursor_z_relative(const GLCanvas3D& canvas)
{
const Vec2d mouse_pos = canvas.get_local_mouse_position();
const Rect& rect = get_bar_rect_screen(canvas);
- float x = (float)mouse_pos(0);
- float y = (float)mouse_pos(1);
+ float x = (float)mouse_pos.x();
+ float y = (float)mouse_pos.y();
float t = rect.get_top();
float b = rect.get_bottom();
@@ -306,6 +315,7 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_screen(const GLCanvas3D& canvas)
return { w - thickness_bar_width(canvas), 0.0f, w, h };
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
{
const Size& cnv_size = canvas.get_canvas_size();
@@ -314,10 +324,15 @@ Rect GLCanvas3D::LayersEditing::get_bar_rect_viewport(const GLCanvas3D& canvas)
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
return { (half_w - thickness_bar_width(canvas)) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom };
}
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
bool GLCanvas3D::LayersEditing::is_initialized() const
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ return wxGetApp().get_shader("variable_layer_height_attr") != nullptr;
+#else
return wxGetApp().get_shader("variable_layer_height") != nullptr;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) const
@@ -346,9 +361,25 @@ std::string GLCanvas3D::LayersEditing::get_tooltip(const GLCanvas3D& canvas) con
return ret;
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas)
+#else
void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Size cnv_size = canvas.get_canvas_size();
+ const float cnv_width = (float)cnv_size.get_width();
+ const float cnv_height = (float)cnv_size.get_height();
+ if (cnv_width == 0.0f || cnv_height == 0.0f)
+ return;
+
+ const float cnv_inv_width = 1.0f / cnv_width;
+
+ GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -359,33 +390,50 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
shader->set_uniform("z_cursor", m_object_max_z * this->get_cursor_z_relative(canvas));
shader->set_uniform("z_cursor_band_width", band_width);
shader->set_uniform("object_max_z", m_object_max_z);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("view_model_matrix", Transform3d::Identity());
+ shader->set_uniform("projection_matrix", Transform3d::Identity());
+ shader->set_uniform("normal_matrix", (Matrix3d)Eigen::Matrix3d::Identity());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id));
// Render the color bar
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_profile.background.is_initialized() || m_profile.old_canvas_width != cnv_width) {
+ m_profile.old_canvas_width = cnv_width;
+#else
if (!m_profile.background.is_initialized() || m_profile.dirty) {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_profile.background.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
init_data.reserve_vertices(4);
init_data.reserve_indices(6);
// vertices
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float l = 1.0f - 2.0f * THICKNESS_BAR_WIDTH * cnv_inv_width;
+ const float r = 1.0f;
+ const float t = 1.0f;
+ const float b = -1.0f;
+#else
const float l = bar_rect.get_left();
const float r = bar_rect.get_right();
const float t = bar_rect.get_top();
const float b = bar_rect.get_bottom();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f));
init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f));
init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f));
init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f));
// indices
- init_data.add_ushort_triangle(0, 1, 2);
- init_data.add_ushort_triangle(2, 3, 0);
+ init_data.add_triangle(0, 1, 2);
+ init_data.add_triangle(2, 3, 0);
m_profile.background.init_from(std::move(init_data));
}
@@ -404,72 +452,115 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3
::glTexCoord2f(1.0f, 1.0f); ::glVertex2f(r, t);
::glTexCoord2f(0.0f, 1.0f); ::glVertex2f(l, t);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
shader->stop_using();
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLCanvas3D::LayersEditing::render_profile(const GLCanvas3D& canvas)
+#else
void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
//FIXME show some kind of legend.
if (!m_slicing_parameters)
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Size cnv_size = canvas.get_canvas_size();
+ const float cnv_width = (float)cnv_size.get_width();
+ const float cnv_height = (float)cnv_size.get_height();
+ if (cnv_width == 0.0f || cnv_height == 0.0f)
+ return;
+
+ // Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
+ const float scale_x = THICKNESS_BAR_WIDTH / float(1.12 * m_slicing_parameters->max_layer_height);
+ const float scale_y = cnv_height / m_object_max_z;
+
+ const float cnv_inv_width = 1.0f / cnv_width;
+ const float cnv_inv_height = 1.0f / cnv_height;
+#else
// Make the vertical bar a bit wider so the layer height curve does not touch the edge of the bar region.
const float scale_x = bar_rect.get_width() / float(1.12 * m_slicing_parameters->max_layer_height);
const float scale_y = bar_rect.get_height() / m_object_max_z;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// Baseline
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_profile.baseline.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) {
+#else
if (!m_profile.baseline.is_initialized() || m_profile.dirty) {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_profile.baseline.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2 };
init_data.color = ColorRGBA::BLACK();
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
// vertices
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float axis_x = 2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_slicing_parameters->layer_height) * scale_x) * cnv_inv_width - 0.5f);
+ init_data.add_vertex(Vec2f(axis_x, -1.0f));
+ init_data.add_vertex(Vec2f(axis_x, 1.0f));
+#else
const float x = bar_rect.get_left() + float(m_slicing_parameters->layer_height) * scale_x;
init_data.add_vertex(Vec2f(x, bar_rect.get_bottom()));
init_data.add_vertex(Vec2f(x, bar_rect.get_top()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_profile.baseline.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_profile.profile.is_initialized() || m_profile.old_layer_height_profile != m_layer_height_profile) {
+#else
if (!m_profile.profile.is_initialized() || m_profile.dirty || m_profile.old_layer_height_profile != m_layer_height_profile) {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_profile.old_layer_height_profile = m_layer_height_profile;
m_profile.profile.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::index_type(m_layer_height_profile.size() / 2) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P2 };
init_data.color = ColorRGBA::BLUE();
init_data.reserve_vertices(m_layer_height_profile.size() / 2);
init_data.reserve_indices(m_layer_height_profile.size() / 2);
// vertices + indices
for (unsigned int i = 0; i < (unsigned int)m_layer_height_profile.size(); i += 2) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ init_data.add_vertex(Vec2f(2.0f * ((cnv_width - THICKNESS_BAR_WIDTH + float(m_layer_height_profile[i + 1]) * scale_x) * cnv_inv_width - 0.5f),
+ 2.0f * (float(m_layer_height_profile[i]) * scale_y * cnv_inv_height - 0.5)));
+#else
init_data.add_vertex(Vec2f(bar_rect.get_left() + float(m_layer_height_profile[i + 1]) * scale_x,
bar_rect.get_bottom() + float(m_layer_height_profile[i]) * scale_y));
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_index((unsigned short)i / 2);
- else
- init_data.add_uint_index(i / 2);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ init_data.add_index(i / 2);
}
m_profile.profile.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("view_model_matrix", Transform3d::Identity());
+ shader->set_uniform("projection_matrix", Transform3d::Identity());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_profile.baseline.render();
m_profile.profile.render();
shader->stop_using();
@@ -490,7 +581,7 @@ void GLCanvas3D::LayersEditing::render_profile(const Rect& bar_rect)
for (unsigned int i = 0; i < m_layer_height_profile.size(); i += 2)
::glVertex2f(bar_rect.get_left() + (float)m_layer_height_profile[i + 1] * scale_x, bar_rect.get_bottom() + (float)m_layer_height_profile[i] * scale_y);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const GLVolumeCollection& volumes)
@@ -503,7 +594,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
if (current_shader != nullptr)
current_shader->stop_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("variable_layer_height");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -517,6 +612,11 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
shader->set_uniform("z_cursor", float(m_object_max_z) * float(this->get_cursor_z_relative(canvas)));
shader->set_uniform("z_cursor_band_width", float(this->band_width));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
// Initialize the layer height texture mapping.
const GLsizei w = (GLsizei)m_layers_texture.width;
const GLsizei h = (GLsizei)m_layers_texture.height;
@@ -535,6 +635,12 @@ void GLCanvas3D::LayersEditing::render_volumes(const GLCanvas3D& canvas, const G
shader->set_uniform("volume_world_matrix", glvolume->world_matrix());
shader->set_uniform("object_max_z", 0.0f);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d view_model_matrix = camera.get_view_matrix() * glvolume->world_matrix();
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
glvolume->render();
}
// Revert back to the previous shader.
@@ -882,18 +988,18 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
if (polygons.empty())
return;
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
size_t triangles_count = 0;
for (const Polygon& poly : polygons) {
triangles_count += poly.points.size() - 2;
}
const size_t vertices_count = 3 * triangles_count;
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (m_render_fill) {
GLModel::Geometry fill_data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::UINT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ fill_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
fill_data.color = { 0.3333f, 0.0f, 0.0f, 0.5f };
// vertices + indices
@@ -907,7 +1013,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
fill_data.add_vertex((Vec3f)(v.cast() + 0.0125f * Vec3f::UnitZ())); // add a small positive z to avoid z-fighting
++vertices_counter;
if (vertices_counter % 3 == 0)
- fill_data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
+ fill_data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
}
@@ -937,10 +1043,10 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
fill_data.entities.emplace_back(entity);
m_fill.init_from(fill_data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_perimeter.init_from(polygons, 0.025f); // add a small positive z to avoid z-fighting
#else
GLModel::Geometry perimeter_data;
@@ -960,7 +1066,7 @@ void GLCanvas3D::SequentialPrintClearance::set_polygons(const Polygons& polygons
}
m_perimeter.init_from(perimeter_data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLCanvas3D::SequentialPrintClearance::render()
@@ -968,26 +1074,36 @@ void GLCanvas3D::SequentialPrintClearance::render()
const ColorRGBA FILL_COLOR = { 1.0f, 0.0f, 0.0f, 0.5f };
const ColorRGBA NO_FILL_COLOR = { 1.0f, 1.0f, 1.0f, 0.75f };
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader == nullptr)
return;
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
glsafe(::glEnable(GL_DEPTH_TEST));
glsafe(::glDisable(GL_CULL_FACE));
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_perimeter.set_color(m_render_fill ? FILL_COLOR : NO_FILL_COLOR);
#else
m_perimeter.set_color(-1, m_render_fill ? FILL_COLOR : NO_FILL_COLOR);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_perimeter.render();
m_fill.render();
@@ -1156,7 +1272,7 @@ bool GLCanvas3D::init()
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
// Set antialiasing / multisampling
glsafe(::glDisable(GL_LINE_SMOOTH));
glsafe(::glDisable(GL_POLYGON_SMOOTH));
@@ -1186,7 +1302,7 @@ bool GLCanvas3D::init()
// A handy trick -- have surface material mirror the color.
glsafe(::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE));
glsafe(::glEnable(GL_COLOR_MATERIAL));
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (m_multisample_allowed)
glsafe(::glEnable(GL_MULTISAMPLE));
@@ -1194,11 +1310,11 @@ bool GLCanvas3D::init()
if (m_main_toolbar.is_enabled())
m_layers_editing.init();
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
// on linux the gl context is not valid until the canvas is not shown on screen
// we defer the geometry finalization of volumes until the first call to render()
m_volumes.finalize_geometry(true);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
if (m_gizmos.is_enabled() && !m_gizmos.init())
std::cout << "Unable to initialize gizmos: please, check that all the required textures are available" << std::endl;
@@ -1551,6 +1667,10 @@ void GLCanvas3D::render()
wxGetApp().plater()->init_environment_texture();
#endif // ENABLE_ENVIRONMENT_MAP
+#if ENABLE_GLMODEL_STATISTICS
+ GLModel::reset_statistics_counters();
+#endif // ENABLE_GLMODEL_STATISTICS
+
const Size& cnv_size = get_canvas_size();
// Probably due to different order of events on Linux/GTK2, when one switched from 3D scene
// to preview, this was called before canvas had its final size. It reported zero width
@@ -1600,7 +1720,11 @@ void GLCanvas3D::render()
_render_gcode();
_render_sla_slices();
_render_selection();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ _render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), true);
+#else
_render_bed(!camera.is_looking_downward(), true);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
_render_objects(GLVolumeCollection::ERenderType::Transparent);
_render_sequential_clearance();
@@ -1660,6 +1784,9 @@ void GLCanvas3D::render()
#if ENABLE_CAMERA_STATISTICS
camera.debug_render();
#endif // ENABLE_CAMERA_STATISTICS
+#if ENABLE_GLMODEL_STATISTICS
+ GLModel::render_statistics();
+#endif // ENABLE_GLMODEL_STATISTICS
std::string tooltip;
@@ -1807,11 +1934,11 @@ std::vector GLCanvas3D::load_object(const ModelObject& model_object, int ob
instance_idxs.emplace_back(i);
}
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
return m_volumes.load_object(&model_object, obj_idx, instance_idxs);
#else
return m_volumes.load_object(&model_object, obj_idx, instance_idxs, m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
std::vector GLCanvas3D::load_object(const Model& model, int obj_idx)
@@ -2036,11 +2163,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
// Note the index of the loaded volume, so that we can reload the main model GLVolume with the hollowed mesh
// later in this function.
it->volume_idx = m_volumes.volumes.size();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx);
#else
m_volumes.load_object_volume(&model_object, obj_idx, volume_idx, instance_idx, m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_volumes.volumes.back()->geometry_id = key.geometry_id;
update_object_list = true;
} else {
@@ -2097,48 +2224,48 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
GLVolume &volume = *m_volumes.volumes[it->volume_idx];
if (! volume.offsets.empty() && state.step[istep].timestamp != volume.offsets.front()) {
// The backend either produced a new hollowed mesh, or it invalidated the one that the front end has seen.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.reset();
#else
volume.indexed_vertex_array.release_geometry();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (state.step[istep].state == PrintStateBase::DONE) {
TriangleMesh mesh = print_object->get_mesh(slaposDrillHoles);
assert(! mesh.empty());
mesh.transform(sla_print->sla_trafo(*m_model->objects[volume.object_idx()]).inverse());
#if ENABLE_SMOOTH_NORMALS
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.init_from(mesh, true);
#else
volume.indexed_vertex_array.load_mesh(mesh, true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#else
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.init_from(mesh);
#else
volume.indexed_vertex_array.load_mesh(mesh);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_SMOOTH_NORMALS
}
else {
// Reload the original volume.
#if ENABLE_SMOOTH_NORMALS
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true);
#else
volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh(), true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#else
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.model.init_from(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh());
#else
volume.indexed_vertex_array.load_mesh(m_model->objects[volume.object_idx()]->volumes[volume.volume_idx()]->mesh());
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_SMOOTH_NORMALS
}
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
volume.finalize_geometry(true);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
//FIXME it is an ugly hack to write the timestamp into the "offsets" field to not have to add another member variable
// to the GLVolume. We should refactor GLVolume significantly, so that the GLVolume will not contain member variables
@@ -2168,11 +2295,11 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
for (size_t istep = 0; istep < sla_steps.size(); ++istep)
if (!instances[istep].empty())
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp);
#else
m_volumes.load_object_auxiliary(print_object, object_idx, instances[istep], sla_steps[istep], state.step[istep].timestamp, m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
// Shift-up all volumes of the object so that it has the right elevation with respect to the print bed
@@ -2202,7 +2329,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
float depth = print->wipe_tower_data(extruders_count).depth;
float brim_width = print->wipe_tower_data(extruders_count).brim_width;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview(
x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
@@ -2222,7 +2349,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower),
brim_width, m_initialized);
#endif // ENABLE_WIPETOWER_OBJECTID_1000_REMOVAL
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (volume_idx_wipe_tower_old != -1)
map_glvolume_old_to_new[volume_idx_wipe_tower_old] = volume_idx_wipe_tower_new;
}
@@ -2282,7 +2409,7 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re
m_dirty = true;
}
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume& vol_old, bool gl_initialized, size_t prealloc_size = VERTEX_BUFFER_RESERVE_SIZE)
{
// Assign the large pre-allocated buffers to the new GLVolume.
@@ -2297,15 +2424,15 @@ static void reserve_new_volume_finalize_old_volume(GLVolume& vol_new, GLVolume&
// Finalize the old geometry, possibly move data to the graphics card.
vol_old.finalize_geometry(gl_initialized);
}
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void GLCanvas3D::load_gcode_preview(const GCodeProcessorResult& gcode_result, const std::vector& str_tool_colors)
{
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_gcode_viewer.load(gcode_result, *this->fff_print());
#else
m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (wxGetApp().is_editor()) {
m_gcode_viewer.update_shells_color_by_extruder(m_config);
@@ -2778,7 +2905,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
m_dirty = true;
},
[this](const Vec3d& direction, bool slow, bool camera_space) {
- m_selection.start_dragging();
+ m_selection.setup_cache();
double multiplier = slow ? 1.0 : 10.0;
Vec3d displacement;
@@ -2791,7 +2918,6 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
displacement = multiplier * direction;
m_selection.translate(displacement);
- m_selection.stop_dragging();
m_dirty = true;
}
);
@@ -2894,9 +3020,8 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
m_dirty = true;
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
auto do_rotate = [this](double angle_z_rad) {
- m_selection.start_dragging();
+ m_selection.setup_cache();
m_selection.rotate(Vec3d(0.0, 0.0, angle_z_rad), TransformationType(TransformationType::World_Relative_Joint));
- m_selection.stop_dragging();
m_dirty = true;
// wxGetApp().obj_manipul()->set_dirty();
};
@@ -3392,7 +3517,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
// The dragging operation is initiated.
m_mouse.drag.move_volume_idx = volume_idx;
- m_selection.start_dragging();
#if ENABLE_NEW_CAMERA_MOVEMENTS_CTRL_ROTATE
if (!evt.CmdDown())
#endif // ENABLE_NEW_CAMERA_MOVEMENTS_CTRL_ROTATE
@@ -3524,9 +3648,6 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
}
else if (evt.LeftUp() || evt.MiddleUp() || evt.RightUp()) {
- if (evt.LeftUp() && m_selection.is_dragging())
- m_selection.stop_dragging();
-
if (m_layers_editing.state != LayersEditing::Unknown) {
m_layers_editing.state = LayersEditing::Unknown;
_stop_timer();
@@ -4208,8 +4329,12 @@ bool GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x)
ImGuiWrapper* imgui = wxGetApp().imgui();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ imgui->set_next_window_pos(pos_x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#else
const float x = pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
imgui->set_next_window_pos(x, m_undoredo_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
std::string title = is_undo ? L("Undo History") : L("Redo History");
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
@@ -4248,8 +4373,12 @@ bool GLCanvas3D::_render_search_list(float pos_x)
bool action_taken = false;
ImGuiWrapper* imgui = wxGetApp().imgui();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ imgui->set_next_window_pos(pos_x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#else
const float x = /*pos_x * (float)wxGetApp().plater()->get_camera().get_zoom() + */0.5f * (float)get_canvas_size().get_width();
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
std::string title = L("Search");
imgui->begin(_(title), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
@@ -4302,9 +4431,13 @@ bool GLCanvas3D::_render_arrange_menu(float pos_x)
{
ImGuiWrapper *imgui = wxGetApp().imgui();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ imgui->set_next_window_pos(pos_x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#else
auto canvas_w = float(get_canvas_size().get_width());
const float x = pos_x * float(wxGetApp().plater()->get_camera().get_zoom()) + 0.5f * canvas_w;
imgui->set_next_window_pos(x, m_main_toolbar.get_height(), ImGuiCond_Always, 0.5f, 0.0f);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
imgui->begin(_L("Arrange options"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
@@ -4429,6 +4562,10 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
camera.zoom_to_box(volumes_box);
camera.apply_view_matrix();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d& view_matrix = camera.get_view_matrix();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
double near_z = -1.0;
double far_z = -1.0;
@@ -4436,14 +4573,22 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
// extends the near and far z of the frustrum to avoid the bed being clipped
// box in eye space
- BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(camera.get_view_matrix());
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(view_matrix);
+#else
+ const BoundingBoxf3 t_bed_box = m_bed.extended_bounding_box().transformed(camera.get_view_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
near_z = -t_bed_box.max.z();
far_z = -t_bed_box.min.z();
}
camera.apply_projection(volumes_box, near_z, far_z);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -4456,15 +4601,25 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
shader->start_using();
shader->set_uniform("emission_factor", 0.0f);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
for (GLVolume* vol : visible_volumes) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
vol->model.set_color((vol->printable && !vol->is_outside) ? (current_printer_technology() == ptSLA ? vol->color : ColorRGBA::ORANGE()) : ColorRGBA::GRAY());
#else
shader->set_uniform("uniform_color", (vol->printable && !vol->is_outside) ? (current_printer_technology() == ptSLA ? vol->color : ColorRGBA::ORANGE()) : ColorRGBA::GRAY());
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// the volume may have been deactivated by an active gizmo
- bool is_active = vol->is_active;
+ const bool is_active = vol->is_active;
vol->is_active = true;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d matrix = view_matrix * vol->world_matrix();
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", projection_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
vol->render();
vol->is_active = is_active;
}
@@ -4474,7 +4629,11 @@ void GLCanvas3D::_render_thumbnail_internal(ThumbnailData& thumbnail_data, const
glsafe(::glDisable(GL_DEPTH_TEST));
if (thumbnail_params.show_bed)
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ _render_bed(view_matrix, projection_matrix, !camera.is_looking_downward(), false);
+#else
_render_bed(!camera.is_looking_downward(), false);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// restore background color
if (thumbnail_params.transparent_background)
@@ -4735,13 +4894,15 @@ bool GLCanvas3D::_init_main_toolbar()
background_data.right = 16;
background_data.bottom = 16;
- if (!m_main_toolbar.init(background_data))
- {
+ if (!m_main_toolbar.init(background_data)) {
// unable to init the toolbar texture, disable it
m_main_toolbar.set_enabled(false);
return true;
}
// init arrow
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_main_toolbar.init_arrow("toolbar_arrow_2.svg"))
+#else
BackgroundTexture::Metadata arrow_data;
arrow_data.filename = "toolbar_arrow.svg";
arrow_data.left = 0;
@@ -4749,14 +4910,16 @@ bool GLCanvas3D::_init_main_toolbar()
arrow_data.right = 0;
arrow_data.bottom = 0;
if (!m_main_toolbar.init_arrow(arrow_data))
- {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
BOOST_LOG_TRIVIAL(error) << "Main toolbar failed to load arrow texture.";
- }
+
// m_gizmos is created at constructor, thus we can init arrow here.
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_gizmos.init_arrow("toolbar_arrow_2.svg"))
+#else
if (!m_gizmos.init_arrow(arrow_data))
- {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
BOOST_LOG_TRIVIAL(error) << "Gizmos manager failed to load arrow texture.";
- }
// m_main_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
m_main_toolbar.set_layout_type(GLToolbar::Layout::Horizontal);
@@ -4803,9 +4966,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.right.toggable = true;
item.right.render_callback = [this](float left, float right, float, float) {
if (m_canvas != nullptr)
- {
_render_arrange_menu(0.5f * (left + right));
- }
};
if (!m_main_toolbar.add_item(item))
return false;
@@ -4908,8 +5069,7 @@ bool GLCanvas3D::_init_main_toolbar()
item.sprite_id = 11;
item.left.toggable = true;
item.left.render_callback = [this](float left, float right, float, float) {
- if (m_canvas != nullptr)
- {
+ if (m_canvas != nullptr) {
if (_render_search_list(0.5f * (left + right)))
_deactivate_search_toolbar_item();
}
@@ -4956,14 +5116,16 @@ bool GLCanvas3D::_init_undoredo_toolbar()
background_data.right = 16;
background_data.bottom = 16;
- if (!m_undoredo_toolbar.init(background_data))
- {
+ if (!m_undoredo_toolbar.init(background_data)) {
// unable to init the toolbar texture, disable it
m_undoredo_toolbar.set_enabled(false);
return true;
}
// init arrow
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_undoredo_toolbar.init_arrow("toolbar_arrow_2.svg"))
+#else
BackgroundTexture::Metadata arrow_data;
arrow_data.filename = "toolbar_arrow.svg";
arrow_data.left = 0;
@@ -4971,9 +5133,8 @@ bool GLCanvas3D::_init_undoredo_toolbar()
arrow_data.right = 0;
arrow_data.bottom = 0;
if (!m_undoredo_toolbar.init_arrow(arrow_data))
- {
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
BOOST_LOG_TRIVIAL(error) << "Undo/Redo toolbar failed to load arrow texture.";
- }
// m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Vertical);
m_undoredo_toolbar.set_layout_type(GLToolbar::Layout::Horizontal);
@@ -4993,8 +5154,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
item.right.toggable = true;
item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; };
item.right.render_callback = [this](float left, float right, float, float) {
- if (m_canvas != nullptr)
- {
+ if (m_canvas != nullptr) {
if (_render_undo_redo_stack(true, 0.5f * (left + right)))
_deactivate_undo_redo_toolbar_items();
}
@@ -5013,8 +5173,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
new_additional_tooltip = (boost::format(_utf8(L("Next Undo action: %1%"))) % action).str();
}
- if (new_additional_tooltip != curr_additional_tooltip)
- {
+ if (new_additional_tooltip != curr_additional_tooltip) {
m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip);
set_tooltip("");
}
@@ -5031,8 +5190,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
item.left.action_callback = [this]() { post_event(SimpleEvent(EVT_GLCANVAS_REDO)); };
item.right.action_callback = [this]() { m_imgui_undo_redo_hovered_pos = -1; };
item.right.render_callback = [this](float left, float right, float, float) {
- if (m_canvas != nullptr)
- {
+ if (m_canvas != nullptr) {
if (_render_undo_redo_stack(false, 0.5f * (left + right)))
_deactivate_undo_redo_toolbar_items();
}
@@ -5051,8 +5209,7 @@ bool GLCanvas3D::_init_undoredo_toolbar()
new_additional_tooltip = (boost::format(_utf8(L("Next Redo action: %1%"))) % action).str();
}
- if (new_additional_tooltip != curr_additional_tooltip)
- {
+ if (new_additional_tooltip != curr_additional_tooltip) {
m_undoredo_toolbar.set_additional_tooltip(id, new_additional_tooltip);
set_tooltip("");
}
@@ -5196,7 +5353,12 @@ void GLCanvas3D::_picking_pass()
if (m_camera_clipping_plane.is_active())
::glDisable(GL_CLIP_PLANE0);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward());
+#else
_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_gizmos.render_current_gizmo_for_picking_pass();
@@ -5252,7 +5414,12 @@ void GLCanvas3D::_rectangular_selection_picking_pass()
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_volumes_for_picking();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ _render_bed_for_picking(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward());
+#else
_render_bed_for_picking(!wxGetApp().plater()->get_camera().is_looking_downward());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (m_multisample_allowed)
glsafe(::glEnable(GL_MULTISAMPLE));
@@ -5325,23 +5492,25 @@ void GLCanvas3D::_render_background()
use_error_color &= m_gcode_viewer.has_data() && !m_gcode_viewer.is_contained_in_bed();
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
glsafe(::glMatrixMode(GL_PROJECTION));
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
// Draws a bottom to top gradient over the complete screen.
glsafe(::glDisable(GL_DEPTH_TEST));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
const ColorRGBA bottom_color = use_error_color ? ERROR_BG_DARK_COLOR : DEFAULT_BG_DARK_COLOR;
if (!m_background.is_initialized()) {
m_background.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
init_data.reserve_vertices(4);
init_data.reserve_indices(6);
@@ -5352,18 +5521,21 @@ void GLCanvas3D::_render_background()
init_data.add_vertex(Vec2f(-1.0f, 1.0f), Vec2f(0.0f, 1.0f));
// indices
- init_data.add_ushort_triangle(0, 1, 2);
- init_data.add_ushort_triangle(2, 3, 0);
+ init_data.add_triangle(0, 1, 2);
+ init_data.add_triangle(2, 3, 0);
m_background.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("background_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("background");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
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();
}
@@ -5377,16 +5549,22 @@ void GLCanvas3D::_render_background()
::glVertex2f(1.0f, 1.0f);
::glVertex2f(-1.0f, 1.0f);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glEnable(GL_DEPTH_TEST));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
glsafe(::glMatrixMode(GL_MODELVIEW));
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLCanvas3D::_render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes)
+#else
void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
float scale_factor = 1.0;
#if ENABLE_RETINA_GL
@@ -5400,17 +5578,29 @@ void GLCanvas3D::_render_bed(bool bottom, bool show_axes)
&& m_gizmos.get_current_type() != GLGizmosManager::Seam
&& m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_bed.render(*this, view_matrix, projection_matrix, bottom, scale_factor, show_axes, show_texture);
+#else
m_bed.render(*this, bottom, scale_factor, show_axes, show_texture);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLCanvas3D::_render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom)
+#else
void GLCanvas3D::_render_bed_for_picking(bool bottom)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
float scale_factor = 1.0;
#if ENABLE_RETINA_GL
scale_factor = m_retina_helper->get_scale_factor();
#endif // ENABLE_RETINA_GL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_bed.render_for_picking(*this, view_matrix, projection_matrix, bottom, scale_factor);
+#else
m_bed.render_for_picking(*this, bottom, scale_factor);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
@@ -5467,7 +5657,11 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify);
#endif // ENABLE_SHOW_NON_MANIFOLD_EDGES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
@@ -5478,18 +5672,33 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
{
if (m_picking_enabled && !m_gizmos.is_dragging() && m_layers_editing.is_enabled() && (m_layers_editing.last_object_id != -1) && (m_layers_editing.object_max_z() > 0.0f)) {
int object_id = m_layers_editing.last_object_id;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_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);
+ });
+#else
m_volumes.render(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);
});
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// Let LayersEditing handle rendering of the active object using the layer height profile shader.
m_layers_editing.render_volumes(*this, m_volumes);
}
else {
// do not cull backfaces to show broken geometry, if any
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ m_volumes.render(type, m_picking_enabled, camera.get_view_matrix(), camera.get_projection_matrix(), [this](const GLVolume& volume) {
+ return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
+ });
+#else
m_volumes.render(type, m_picking_enabled, wxGetApp().plater()->get_camera().get_view_matrix(), [this](const GLVolume& volume) {
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
});
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
// In case a painting gizmo is open, it should render the painted triangles
@@ -5508,7 +5717,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type)
}
case GLVolumeCollection::ERenderType::Transparent:
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ m_volumes.render(type, false, camera.get_view_matrix(), camera.get_projection_matrix());
+#else
m_volumes.render(type, false, wxGetApp().plater()->get_camera().get_view_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
break;
}
}
@@ -5616,6 +5830,7 @@ void GLCanvas3D::_check_and_update_toolbar_icon_scale()
void GLCanvas3D::_render_overlays()
{
glsafe(::glDisable(GL_DEPTH_TEST));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// ensure that the textures are renderered inside the frustrum
@@ -5624,6 +5839,7 @@ void GLCanvas3D::_render_overlays()
// ensure that the overlay fits the frustrum near z plane
double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
_check_and_update_toolbar_icon_scale();
@@ -5662,22 +5878,30 @@ void GLCanvas3D::_render_overlays()
}
m_labels.render(sorted_instances);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLCanvas3D::_render_volumes_for_picking() const
{
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// do not cull backfaces to show broken geometry, if any
glsafe(::glDisable(GL_CULL_FACE));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
const Transform3d& view_matrix = wxGetApp().plater()->get_camera().get_view_matrix();
for (size_t type = 0; type < 2; ++ type) {
@@ -5688,21 +5912,28 @@ void GLCanvas3D::_render_volumes_for_picking() const
// we reserve color = (0,0,0) for occluders (as the printbed)
// so we shift volumes' id by 1 to get the proper color
const unsigned int id = 1 + volume.second.first;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume.first->model.set_color(picking_decode(id));
shader->start_using();
#else
glsafe(::glColor4fv(picking_decode(id).data()));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix() * volume.first->world_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
volume.first->render();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glEnable(GL_CULL_FACE));
}
@@ -5728,9 +5959,7 @@ void GLCanvas3D::_render_gizmos_overlay()
m_gizmos.render_overlay();
if (m_gizmo_highlighter.m_render_arrow)
- {
m_gizmos.render_arrow(*this, m_gizmo_highlighter.m_gizmo_type);
- }
}
void GLCanvas3D::_render_main_toolbar()
@@ -5738,20 +5967,26 @@ void GLCanvas3D::_render_main_toolbar()
if (!m_main_toolbar.is_enabled())
return;
- Size cnv_size = get_canvas_size();
- float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
+ const Size cnv_size = get_canvas_size();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float top = 0.5f * (float)cnv_size.get_height();
+#else
+ const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
+ const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
- float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
- float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
- float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom;
+ const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width);
+#else
+ const float left = -0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width) * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_main_toolbar.set_position(top, left);
m_main_toolbar.render(*this);
if (m_toolbar_highlighter.m_render_arrow)
- {
m_main_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item);
- }
}
void GLCanvas3D::_render_undoredo_toolbar()
@@ -5759,33 +5994,43 @@ void GLCanvas3D::_render_undoredo_toolbar()
if (!m_undoredo_toolbar.is_enabled())
return;
- Size cnv_size = get_canvas_size();
+ const Size cnv_size = get_canvas_size();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float top = 0.5f * (float)cnv_size.get_height();
+#else
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
- float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
+ const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
- float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
- float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom;
+ const float collapse_toolbar_width = collapse_toolbar.is_enabled() ? collapse_toolbar.get_width() : 0.0f;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float left = m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width);
+#else
+ const float left = (m_main_toolbar.get_width() - 0.5f * (m_main_toolbar.get_width() + m_undoredo_toolbar.get_width() + collapse_toolbar_width)) * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_undoredo_toolbar.set_position(top, left);
m_undoredo_toolbar.render(*this);
if (m_toolbar_highlighter.m_render_arrow)
- {
m_undoredo_toolbar.render_arrow(*this, m_toolbar_highlighter.m_toolbar_item);
- }
}
void GLCanvas3D::_render_collapse_toolbar() const
{
GLToolbar& collapse_toolbar = wxGetApp().plater()->get_collapse_toolbar();
- Size cnv_size = get_canvas_size();
- float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
+ const Size cnv_size = get_canvas_size();
+ const float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float top = 0.5f * (float)cnv_size.get_height();
+ const float left = 0.5f * (float)cnv_size.get_width() - collapse_toolbar.get_width() - band;
+#else
+ const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
- float band = m_layers_editing.is_enabled() ? (wxGetApp().imgui()->get_style_scaling() * LayersEditing::THICKNESS_BAR_WIDTH) : 0.0;
-
- float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
- float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band) * inv_zoom;
+ const float top = 0.5f * (float)cnv_size.get_height() * inv_zoom;
+ const float left = (0.5f * (float)cnv_size.get_width() - (float)collapse_toolbar.get_width() - band) * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
collapse_toolbar.set_position(top, left);
collapse_toolbar.render(*this);
@@ -5808,12 +6053,18 @@ void GLCanvas3D::_render_view_toolbar() const
view_toolbar.set_icons_size(size);
#endif // ENABLE_RETINA_GL
- Size cnv_size = get_canvas_size();
+ const Size cnv_size = get_canvas_size();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ // places the toolbar on the bottom-left corner of the 3d scene
+ float top = -0.5f * (float)cnv_size.get_height() + view_toolbar.get_height();
+ float left = -0.5f * (float)cnv_size.get_width();
+#else
float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
// places the toolbar on the bottom-left corner of the 3d scene
float top = (-0.5f * (float)cnv_size.get_height() + view_toolbar.get_height()) * inv_zoom;
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
view_toolbar.set_position(top, left);
view_toolbar.render(*this);
}
@@ -5821,54 +6072,59 @@ void GLCanvas3D::_render_view_toolbar() const
#if ENABLE_SHOW_CAMERA_TARGET
void GLCanvas3D::_render_camera_target()
{
- static const double half_length = 5.0;
+ static const float half_length = 5.0f;
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glLineWidth(2.0f));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- const Vec3d& target = wxGetApp().plater()->get_camera().get_target();
- bool target_changed = !m_camera_target.target.isApprox(target);
- m_camera_target.target = target;
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ const Vec3f& target = wxGetApp().plater()->get_camera().get_target().cast();
+ bool target_changed = !m_camera_target.target.isApprox(target.cast());
+ m_camera_target.target = target.cast();
for (int i = 0; i < 3; ++i) {
if (!m_camera_target.axis[i].is_initialized() || target_changed) {
m_camera_target.axis[i].reset();
- GLModel::InitializationData init_data;
- GLModel::InitializationData::Entity entity;
- entity.type = GLModel::PrimitiveType::Lines;
- entity.positions.reserve(2);
+ GLModel::Geometry init_data;
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.color = (i == X) ? ColorRGBA::X() : ((i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
+ init_data.reserve_vertices(2);
+ init_data.reserve_indices(2);
+
+ // vertices
if (i == X) {
- entity.positions.emplace_back(target.x() - half_length, target.y(), target.z());
- entity.positions.emplace_back(target.x() + half_length, target.y(), target.z());
+ init_data.add_vertex(Vec3f(target.x() - half_length, target.y(), target.z()));
+ init_data.add_vertex(Vec3f(target.x() + half_length, target.y(), target.z()));
}
else if (i == Y) {
- entity.positions.emplace_back(target.x(), target.y() - half_length, target.z());
- entity.positions.emplace_back(target.x(), target.y() + half_length, target.z());
+ init_data.add_vertex(Vec3f(target.x(), target.y() - half_length, target.z()));
+ init_data.add_vertex(Vec3f(target.x(), target.y() + half_length, target.z()));
}
else {
- entity.positions.emplace_back(target.x(), target.y(), target.z() - half_length);
- entity.positions.emplace_back(target.x(), target.y(), target.z() + half_length);
- }
- entity.normals.reserve(2);
- for (size_t j = 0; j < 2; ++j) {
- entity.normals.emplace_back(Vec3f::UnitZ());
+ init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() - half_length));
+ init_data.add_vertex(Vec3f(target.x(), target.y(), target.z() + half_length));
}
- entity.indices.reserve(2);
- entity.indices.emplace_back(0);
- entity.indices.emplace_back(1);
+ // indices
+ init_data.add_ushort_line(0, 1);
- init_data.entities.emplace_back(entity);
- m_camera_target.axis[i].init_from(init_data);
- m_camera_target.axis[i].set_color(-1, (i == X) ? ColorRGBA::X() : (i == Y) ? ColorRGBA::Y() : ColorRGBA::Z());
+ m_camera_target.axis[i].init_from(std::move(init_data));
}
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
for (int i = 0; i < 3; ++i) {
m_camera_target.axis[i].render();
}
@@ -5890,7 +6146,7 @@ void GLCanvas3D::_render_camera_target()
::glVertex3d(target.x(), target.y(), target.z() - half_length);
::glVertex3d(target.x(), target.y(), target.z() + half_length);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // ENABLE_SHOW_CAMERA_TARGET
@@ -5913,40 +6169,40 @@ void GLCanvas3D::_render_sla_slices()
if (!obj->is_step_done(slaposSliceSupports))
continue;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
SlaCap::ObjectIdToModelsMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i);
SlaCap::ObjectIdToModelsMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i);
#else
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_bottom = m_sla_caps[0].triangles.find(i);
SlaCap::ObjectIdToTrianglesMap::iterator it_caps_top = m_sla_caps[1].triangles.find(i);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (it_caps_bottom == m_sla_caps[0].triangles.end())
it_caps_bottom = m_sla_caps[0].triangles.emplace(i, SlaCap::Triangles()).first;
if (!m_sla_caps[0].matches(clip_min_z)) {
m_sla_caps[0].z = clip_min_z;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
it_caps_bottom->second.object.reset();
it_caps_bottom->second.supports.reset();
#else
it_caps_bottom->second.object.clear();
it_caps_bottom->second.supports.clear();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
if (it_caps_top == m_sla_caps[1].triangles.end())
it_caps_top = m_sla_caps[1].triangles.emplace(i, SlaCap::Triangles()).first;
if (!m_sla_caps[1].matches(clip_max_z)) {
m_sla_caps[1].z = clip_max_z;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
it_caps_top->second.object.reset();
it_caps_top->second.supports.reset();
#else
it_caps_top->second.object.clear();
it_caps_top->second.supports.clear();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel& bottom_obj_triangles = it_caps_bottom->second.object;
GLModel& bottom_sup_triangles = it_caps_bottom->second.supports;
GLModel& top_obj_triangles = it_caps_top->second.object;
@@ -5956,12 +6212,12 @@ void GLCanvas3D::_render_sla_slices()
Pointf3s &bottom_sup_triangles = it_caps_bottom->second.supports;
Pointf3s &top_obj_triangles = it_caps_top->second.object;
Pointf3s &top_sup_triangles = it_caps_top->second.supports;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
auto init_model = [](GLModel& model, const Pointf3s& triangles, const ColorRGBA& color) {
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(triangles.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(triangles.size());
init_data.reserve_indices(triangles.size() / 3);
init_data.color = color;
@@ -5970,12 +6226,8 @@ void GLCanvas3D::_render_sla_slices()
for (const Vec3d& v : triangles) {
init_data.add_vertex((Vec3f)v.cast());
++vertices_count;
- if (vertices_count % 3 == 0) {
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_triangle((unsigned short)vertices_count - 3, (unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1);
- else
- init_data.add_uint_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1);
- }
+ if (vertices_count % 3 == 0)
+ init_data.add_triangle(vertices_count - 3, vertices_count - 2, vertices_count - 1);
}
if (!init_data.is_empty())
@@ -5987,7 +6239,7 @@ void GLCanvas3D::_render_sla_slices()
#else
if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) &&
!obj->get_slice_index().empty()) {
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
double layer_height = print->default_object_config().layer_height.value;
double initial_layer_height = print->material_config().initial_layer_height.value;
bool left_handed = obj->is_left_handed();
@@ -6007,7 +6259,7 @@ void GLCanvas3D::_render_sla_slices()
if (slice_low.is_valid()) {
const ExPolygons& obj_bottom = slice_low.get_slice(soModel);
const ExPolygons& sup_bottom = slice_low.get_slice(soSupport);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// calculate model bottom cap
if (!bottom_obj_triangles.is_initialized() && !obj_bottom.empty())
init_model(bottom_obj_triangles, triangulate_expolygons_3d(obj_bottom, clip_min_z - plane_shift_z, !left_handed), { 1.0f, 0.37f, 0.0f, 1.0f });
@@ -6021,13 +6273,13 @@ void GLCanvas3D::_render_sla_slices()
// calculate support bottom cap
if (bottom_sup_triangles.empty() && !sup_bottom.empty())
bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, clip_min_z - plane_shift_z, !left_handed);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
if (slice_high.is_valid()) {
const ExPolygons& obj_top = slice_high.get_slice(soModel);
const ExPolygons& sup_top = slice_high.get_slice(soSupport);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// calculate model top cap
if (!top_obj_triangles.is_initialized() && !obj_top.empty())
init_model(top_obj_triangles, triangulate_expolygons_3d(obj_top, clip_max_z + plane_shift_z, left_handed), { 1.0f, 0.37f, 0.0f, 1.0f });
@@ -6041,29 +6293,46 @@ void GLCanvas3D::_render_sla_slices()
// calculate support top cap
if (top_sup_triangles.empty() && !sup_top.empty())
top_sup_triangles = triangulate_expolygons_3d(sup_top, clip_max_z + plane_shift_z, left_handed);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
for (const SLAPrintObject::Instance& inst : obj->instances()) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() *
+ Geometry::assemble_transform(Vec3d(unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0),
+ inst.rotation * Vec3d::UnitZ(), Vec3d::Ones(),
+ obj->is_left_handed() ? Vec3d(-1.0f, 1.0f, 1.0f) : Vec3d::Ones());
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(unscale(inst.shift.x()), unscale(inst.shift.y()), 0.0));
glsafe(::glRotatef(Geometry::rad2deg(inst.rotation), 0.0f, 0.0f, 1.0f));
if (obj->is_left_handed())
// The polygons are mirrored by X.
glsafe(::glScalef(-1.0f, 1.0f, 1.0f));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
bottom_obj_triangles.render();
top_obj_triangles.render();
bottom_sup_triangles.render();
top_sup_triangles.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
shader->stop_using();
@@ -6100,7 +6369,7 @@ void GLCanvas3D::_render_sla_slices()
glsafe(::glPopMatrix());
}
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
@@ -6291,16 +6560,16 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume)
skirt_height = std::min(skirt_height, print_zs.size());
print_zs.erase(print_zs.begin() + skirt_height, print_zs.end());
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume* volume = m_volumes.new_toolpath_volume(color);
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
#else
GLVolume *volume = m_volumes.new_toolpath_volume(color, VERTEX_BUFFER_RESERVE_SIZE);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t i = 0; i < skirt_height; ++ i) {
volume->print_zs.emplace_back(print_zs[i]);
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume->offsets.emplace_back(init_data.indices_count());
if (i == 0)
_3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), init_data);
@@ -6311,28 +6580,28 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume)
if (i == 0)
_3DScene::extrusionentity_to_verts(print->brim(), print_zs[i], Point(0, 0), *volume);
_3DScene::extrusionentity_to_verts(print->skirt(), print_zs[i], Point(0, 0), *volume);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (init_data.vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) {
volume->model.init_from(std::move(init_data));
#else
if (volume->indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLVolume &vol = *volume;
volume = m_volumes.new_toolpath_volume(vol.color);
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume->model.init_from(std::move(init_data));
volume->is_outside = !contains(build_volume, volume->model);
#else
volume->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(volume->indexed_vertex_array.vertices_and_normals_interleaved, volume->indexed_vertex_array.bounding_box());
volume->indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector& str_tool_colors, const std::vector& color_print_values)
@@ -6504,11 +6773,11 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
// Allocate the volume before locking.
GLVolume *volume = new GLVolume(color);
volume->is_extrusion_path = true;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// to prevent sending data to gpu (in the main thread) while
// editing the model geometry
volume->model.disable_render();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
tbb::spin_mutex::scoped_lock lock;
// Lock by ROII, so if the emplace_back() fails, the lock will be released.
lock.acquire(new_volume_mutex);
@@ -6521,7 +6790,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
tbb::blocked_range(0, ctxt.layers.size(), grain_size),
[&ctxt, &new_volume, is_selected_separate_extruder, this](const tbb::blocked_range& range) {
GLVolumePtrs vols;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::vector geometries;
auto select_geometry = [&ctxt, &geometries](size_t layer_idx, int extruder, int feature) -> GLModel::Geometry& {
return geometries[ctxt.color_by_color_print() ?
@@ -6540,32 +6809,32 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
feature
];
};
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (ctxt.color_by_color_print() || ctxt.color_by_tool()) {
for (size_t i = 0; i < ctxt.number_tools(); ++i) {
vols.emplace_back(new_volume(ctxt.color_tool(i)));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
geometries.emplace_back(GLModel::Geometry());
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
else {
vols = { new_volume(ctxt.color_perimeters()), new_volume(ctxt.color_infill()), new_volume(ctxt.color_support()) };
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
geometries = { GLModel::Geometry(), GLModel::Geometry(), GLModel::Geometry() };
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
assert(vols.size() == geometries.size());
for (GLModel::Geometry& g : geometries) {
- g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
}
#else
for (GLVolume *vol : vols)
// Reserving number of vertices (3x position + 3x color)
vol->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++ idx_layer) {
const Layer *layer = ctxt.layers[idx_layer];
@@ -6586,7 +6855,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
continue;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume* vol = vols[i];
if (vol->print_zs.empty() || vol->print_zs.back() != layer->print_z) {
@@ -6601,7 +6870,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
vol->offsets.emplace_back(vol->indexed_vertex_array.quad_indices.size());
vol->offsets.emplace_back(vol->indexed_vertex_array.triangle_indices.size());
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (const PrintInstance &instance : *ctxt.shifted_copies) {
const Point © = instance.shift;
@@ -6614,19 +6883,19 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
continue;
}
if (ctxt.has_perimeters)
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
select_geometry(idx_layer, layerm->region().config().perimeter_extruder.value, 0));
#else
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
volume(idx_layer, layerm->region().config().perimeter_extruder.value, 0));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (ctxt.has_infill) {
for (const ExtrusionEntity *ee : layerm->fills.entities) {
// fill represents infill extrusions of a single island.
const auto *fill = dynamic_cast(ee);
if (! fill->entities.empty())
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
select_geometry(idx_layer, is_solid_infill(fill->entities.front()->role()) ?
layerm->region().config().solid_infill_extruder :
@@ -6638,7 +6907,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
layerm->region().config().solid_infill_extruder :
layerm->region().config().infill_extruder,
1));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
}
@@ -6646,7 +6915,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
const SupportLayer *support_layer = dynamic_cast(layer);
if (support_layer) {
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
_3DScene::extrusionentity_to_verts(extrusion_entity, float(layer->print_z), copy,
select_geometry(idx_layer, (extrusion_entity->role() == erSupportMaterial) ?
support_layer->object()->config().support_material_extruder :
@@ -6658,28 +6927,28 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
support_layer->object()->config().support_material_extruder :
support_layer->object()->config().support_material_interface_extruder,
2));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
}
// Ensure that no volume grows over the limits. If the volume is too large, allocate a new one.
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) {
vol.model.init_from(std::move(geometries[i]));
#else
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
vols[i] = new_volume(vol.color);
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t i = 0; i < vols.size(); ++i) {
if (!geometries[i].is_empty())
vols[i]->model.init_from(std::move(geometries[i]));
@@ -6689,7 +6958,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
// Ideally one would call vol->indexed_vertex_array.finalize() here to move the buffers to the OpenGL driver,
// but this code runs in parallel and the OpenGL driver is not thread safe.
vol->indexed_vertex_array.shrink_to_fit();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
});
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
@@ -6704,14 +6973,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
}
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
v->is_outside = !contains(build_volume, v->model);
// We are done editinig the model, now it can be sent to gpu
v->model.enable_render();
#else
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
@@ -6776,11 +7045,11 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) {
auto *volume = new GLVolume(color);
volume->is_extrusion_path = true;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// to prevent sending data to gpu (in the main thread) while
// editing the model geometry
volume->model.disable_render();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
tbb::spin_mutex::scoped_lock lock;
lock.acquire(new_volume_mutex);
m_volumes.volumes.emplace_back(volume);
@@ -6794,46 +7063,46 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
[&ctxt, &new_volume](const tbb::blocked_range& range) {
// Bounding box of this slab of a wipe tower.
GLVolumePtrs vols;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::vector geometries;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (ctxt.color_by_tool()) {
for (size_t i = 0; i < ctxt.number_tools(); ++i) {
vols.emplace_back(new_volume(ctxt.color_tool(i)));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
geometries.emplace_back(GLModel::Geometry());
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
else {
vols = { new_volume(ctxt.color_support()) };
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
geometries = { GLModel::Geometry() };
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
assert(vols.size() == geometries.size());
for (GLModel::Geometry& g : geometries) {
- g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ g.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
}
#else
for (GLVolume *volume : vols)
// Reserving number of vertices (3x position + 3x color)
volume->indexed_vertex_array.reserve(VERTEX_BUFFER_RESERVE_SIZE / 6);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t idx_layer = range.begin(); idx_layer < range.end(); ++idx_layer) {
const std::vector &layer = ctxt.tool_change(idx_layer);
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
if (vol.print_zs.empty() || vol.print_zs.back() != layer.front().print_z) {
vol.print_zs.emplace_back(layer.front().print_z);
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
vol.offsets.emplace_back(geometries[i].indices_count());
#else
vol.offsets.emplace_back(vol.indexed_vertex_array.quad_indices.size());
vol.offsets.emplace_back(vol.indexed_vertex_array.triangle_indices.size());
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
for (const WipeTower::ToolChangeResult &extrusions : layer) {
@@ -6876,32 +7145,32 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
e_prev = e;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
_3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
geometries[ctxt.volume_idx(e.tool, 0)]);
#else
_3DScene::thick_lines_to_verts(lines, widths, heights, lines.front().a == lines.back().b, extrusions.print_z,
*vols[ctxt.volume_idx(e.tool, 0)]);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
}
for (size_t i = 0; i < vols.size(); ++i) {
GLVolume &vol = *vols[i];
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (geometries[i].vertices_size_bytes() > MAX_VERTEX_BUFFER_SIZE) {
vol.model.init_from(std::move(geometries[i]));
#else
if (vol.indexed_vertex_array.vertices_and_normals_interleaved.size() > MAX_VERTEX_BUFFER_SIZE) {
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
vols[i] = new_volume(vol.color);
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
reserve_new_volume_finalize_old_volume(*vols[i], vol, false);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
}
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (size_t i = 0; i < vols.size(); ++i) {
if (!geometries[i].is_empty())
vols[i]->model.init_from(std::move(geometries[i]));
@@ -6909,7 +7178,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
#else
for (GLVolume *vol : vols)
vol->indexed_vertex_array.shrink_to_fit();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
});
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - finalizing results" << m_volumes.log_memory_info() << log_memory_info();
@@ -6924,14 +7193,14 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, con
}
for (size_t i = volumes_cnt_initial; i < m_volumes.volumes.size(); ++i) {
GLVolume* v = m_volumes.volumes[i];
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
v->is_outside = !contains(build_volume, v->model);
// We are done editinig the model, now it can be sent to gpu
v->model.enable_render();
#else
v->is_outside = ! build_volume.all_paths_inside_vertices_and_normals_interleaved(v->indexed_vertex_array.vertices_and_normals_interleaved, v->indexed_vertex_array.bounding_box());
v->indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info();
@@ -6955,21 +7224,21 @@ void GLCanvas3D::_load_sla_shells()
m_volumes.volumes.emplace_back(new GLVolume(color));
GLVolume& v = *m_volumes.volumes.back();
#if ENABLE_SMOOTH_NORMALS
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
v.model.init_from(mesh, true);
#else
v.indexed_vertex_array.load_mesh(mesh, true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#else
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
v.model.init_from(mesh);
#else
v.indexed_vertex_array.load_mesh(mesh);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#endif // ENABLE_SMOOTH_NORMALS
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
v.indexed_vertex_array.finalize_geometry(m_initialized);
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
v.shader_outside_printer_detection_enabled = outside_printer_detection_enabled;
v.composite_id.volume_id = volume_id;
v.set_instance_offset(unscale(instance.shift.x(), instance.shift.y(), 0.0));
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index 48fef5611..09659faea 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -239,18 +239,24 @@ class GLCanvas3D
int last_object_id{ -1 };
float last_z{ 0.0f };
LayerHeightEditActionType last_action{ LAYER_HEIGHT_EDIT_ACTION_INCREASE };
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
struct Profile
{
GLModel baseline;
GLModel profile;
GLModel background;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ float old_canvas_width{ 0.0f };
+#else
Rect old_bar_rect;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
std::vector old_layer_height_profile;
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
bool dirty{ false };
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
};
Profile m_profile;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
LayersEditing() = default;
~LayersEditing();
@@ -277,7 +283,9 @@ class GLCanvas3D
static float get_cursor_z_relative(const GLCanvas3D& canvas);
static bool bar_rect_contains(const GLCanvas3D& canvas, float x, float y);
static Rect get_bar_rect_screen(const GLCanvas3D& canvas);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
static Rect get_bar_rect_viewport(const GLCanvas3D& canvas);
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
static float get_overlay_window_width() { return LayersEditing::s_overlay_window_width; }
float object_max_z() const { return m_object_max_z; }
@@ -287,8 +295,13 @@ class GLCanvas3D
private:
bool is_initialized() const;
void generate_layer_height_texture();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_active_object_annotations(const GLCanvas3D& canvas);
+ void render_profile(const GLCanvas3D& canvas);
+#else
void render_active_object_annotations(const GLCanvas3D& canvas, const Rect& bar_rect);
void render_profile(const Rect& bar_rect);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void update_slicing_parameters();
static float thickness_bar_width(const GLCanvas3D &canvas);
@@ -335,7 +348,7 @@ class GLCanvas3D
struct SlaCap
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
struct Triangles
{
GLModel object;
@@ -353,7 +366,7 @@ class GLCanvas3D
typedef std::map ObjectIdToTrianglesMap;
double z;
ObjectIdToTrianglesMap triangles;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
SlaCap() { reset(); }
void reset() { z = DBL_MAX; triangles.clear(); }
@@ -620,7 +633,7 @@ private:
}
m_gizmo_highlighter;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SHOW_CAMERA_TARGET
struct CameraTarget
{
@@ -631,7 +644,7 @@ private:
CameraTarget m_camera_target;
#endif // ENABLE_SHOW_CAMERA_TARGET
GLModel m_background;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
public:
explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed);
@@ -940,8 +953,13 @@ private:
void _picking_pass();
void _rectangular_selection_picking_pass();
void _render_background();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes);
+ void _render_bed_for_picking(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom);
+#else
void _render_bed(bool bottom, bool show_axes);
void _render_bed_for_picking(bool bottom);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void _render_objects(GLVolumeCollection::ERenderType type);
void _render_gcode();
#if ENABLE_SHOW_TOOLPATHS_COG
diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp
index 8620c7eaf..b81287ece 100644
--- a/src/slic3r/GUI/GLModel.cpp
+++ b/src/slic3r/GUI/GLModel.cpp
@@ -4,32 +4,40 @@
#include "3DScene.hpp"
#include "GUI_App.hpp"
#include "GLShader.hpp"
+#if ENABLE_GLMODEL_STATISTICS
+#include "Plater.hpp"
+#include "GLCanvas3D.hpp"
+#endif // ENABLE_GLMODEL_STATISTICS
#include "libslic3r/TriangleMesh.hpp"
#include "libslic3r/Model.hpp"
#include "libslic3r/Polygon.hpp"
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/BuildVolume.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+
+#if ENABLE_GLMODEL_STATISTICS
+#include
+#endif // ENABLE_GLMODEL_STATISTICS
#include
#include
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
#include
#include
#include
#endif // ENABLE_SMOOTH_NORMALS
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include
namespace Slic3r {
namespace GUI {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
static void smooth_normals_corner(const TriangleMesh& mesh, std::vector& normals)
{
@@ -56,19 +64,9 @@ static void smooth_normals_corner(const TriangleMesh& mesh, std::vector::iterator it = vertices.begin() + id * stride;
+ const size_t stride = vertex_stride_floats(format);
+ std::vector::const_iterator it = vertices.begin() + id * stride;
vertices.erase(it, it + stride);
}
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
size_t GLModel::Geometry::vertex_stride_floats(const Format& format)
{
@@ -402,21 +319,17 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format)
};
}
-size_t GLModel::Geometry::index_stride_bytes(const Format& format)
+size_t GLModel::Geometry::index_stride_bytes(const Geometry& data)
{
- switch (format.index_type)
+ switch (data.index_type)
{
case EIndexType::UINT: { return sizeof(unsigned int); }
case EIndexType::USHORT: { return sizeof(unsigned short); }
+ case EIndexType::UBYTE: { return sizeof(unsigned char); }
default: { assert(false); return 0; }
};
}
-GLModel::Geometry::EIndexType GLModel::Geometry::index_type(size_t vertices_count)
-{
- return (vertices_count < 65536) ? EIndexType::USHORT : EIndexType::UINT;
-}
-
bool GLModel::Geometry::has_position(const Format& format)
{
switch (format.vertex_layout)
@@ -473,15 +386,19 @@ size_t GLModel::Geometry::indices_count() const
}
return ret;
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_GLMODEL_STATISTICS
+GLModel::Statistics GLModel::s_statistics;
+#endif // ENABLE_GLMODEL_STATISTICS
+
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(Geometry&& data)
#else
void GLModel::init_from(const Geometry& data)
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@@ -541,10 +458,10 @@ void GLModel::init_from(const Geometry& data)
send_to_gpu(rdata, vertices, indices);
m_render_data.emplace_back(rdata);
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SMOOTH_NORMALS
void GLModel::init_from(const TriangleMesh& mesh, bool smooth_normals)
{
@@ -601,9 +518,9 @@ void GLModel::init_from(const TriangleMesh& mesh)
void GLModel::init_from(const indexed_triangle_set& its)
#else
void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bbox)
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@@ -616,7 +533,7 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb
}
Geometry& data = m_render_data.geometry;
- data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(3 * its.indices.size()) };
+ data.format = { Geometry::EPrimitiveType::Triangles, Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(3 * its.indices.size());
data.reserve_indices(3 * its.indices.size());
@@ -630,15 +547,12 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb
data.add_vertex(vertex[j], n);
}
vertices_counter += 3;
- if (data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- data.add_ushort_triangle((unsigned short)vertices_counter - 3, (unsigned short)vertices_counter - 2, (unsigned short)vertices_counter - 1);
- else
- data.add_uint_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
+ data.add_triangle(vertices_counter - 3, vertices_counter - 2, vertices_counter - 1);
}
// update bounding box
for (size_t i = 0; i < vertices_count(); ++i) {
- m_bounding_box.merge(m_render_data.geometry.extract_position_3(i).cast());
+ m_bounding_box.merge(data.extract_position_3(i).cast());
}
#else
if (!m_render_data.empty()) // call reset() if you want to reuse this model
@@ -670,19 +584,19 @@ void GLModel::init_from(const indexed_triangle_set& its, const BoundingBoxf3 &bb
send_to_gpu(data, vertices, indices);
m_render_data.emplace_back(data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(const indexed_triangle_set& its)
{
init_from(its, bounding_box(its));
}
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::init_from(const Polygons& polygons, float z)
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (is_initialized()) {
// call reset() if you want to reuse this model
assert(false);
@@ -695,7 +609,7 @@ void GLModel::init_from(const Polygons& polygons, float z)
}
Geometry& data = m_render_data.geometry;
- data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3, Geometry::EIndexType::UINT };
+ data.format = { Geometry::EPrimitiveType::Lines, Geometry::EVertexLayout::P3 };
size_t segments_count = 0;
for (const Polygon& polygon : polygons) {
@@ -714,13 +628,13 @@ void GLModel::init_from(const Polygons& polygons, float z)
data.add_vertex(Vec3f(unscale(p0.x()), unscale(p0.y()), z));
data.add_vertex(Vec3f(unscale(p1.x()), unscale(p1.y()), z));
vertices_counter += 2;
- data.add_uint_line(vertices_counter - 2, vertices_counter - 1);
+ data.add_line(vertices_counter - 2, vertices_counter - 1);
}
}
// update bounding box
for (size_t i = 0; i < vertices_count(); ++i) {
- m_bounding_box.merge(m_render_data.geometry.extract_position_3(i).cast());
+ m_bounding_box.merge(data.extract_position_3(i).cast());
}
#else
auto append_polygon = [](const Polygon& polygon, float z, GUI::GLModel::Geometry& data) {
@@ -746,7 +660,7 @@ void GLModel::init_from(const Polygons& polygons, float z)
append_polygon(polygon, z, init_data);
}
init_from(init_data);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
bool GLModel::init_from_file(const std::string& filename)
@@ -765,19 +679,19 @@ bool GLModel::init_from_file(const std::string& filename)
return false;
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
init_from(model.mesh());
#else
const TriangleMesh& mesh = model.mesh();
init_from(mesh.its, mesh.bounding_box());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_filename = filename;
return true;
}
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::set_color(int entity_id, const ColorRGBA& color)
{
for (size_t i = 0; i < m_render_data.size(); ++i) {
@@ -791,25 +705,31 @@ ColorRGBA GLModel::get_color(size_t entity_id) const
if (entity_id < 0 || entity_id >= m_render_data.size()) return ColorRGBA{};
return m_render_data[entity_id].color;
}
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::reset()
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// release gpu memory
if (m_render_data.ibo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_render_data.ibo_id));
m_render_data.ibo_id = 0;
+#if ENABLE_GLMODEL_STATISTICS
+ s_statistics.gpu_memory.indices.current -= indices_size_bytes();
+#endif // ENABLE_GLMODEL_STATISTICS
}
if (m_render_data.vbo_id > 0) {
glsafe(::glDeleteBuffers(1, &m_render_data.vbo_id));
m_render_data.vbo_id = 0;
+#if ENABLE_GLMODEL_STATISTICS
+ s_statistics.gpu_memory.vertices.current -= vertices_size_bytes();
+#endif // ENABLE_GLMODEL_STATISTICS
}
m_render_data.vertices_count = 0;
m_render_data.indices_count = 0;
m_render_data.geometry.vertices = std::vector();
- m_render_data.geometry.indices = std::vector();
+ m_render_data.geometry.indices = std::vector();
#else
for (RenderData& data : m_render_data) {
// release gpu memory
@@ -820,12 +740,12 @@ void GLModel::reset()
}
m_render_data.clear();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_bounding_box = BoundingBoxf3();
m_filename = std::string();
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
static GLenum get_primitive_mode(const GLModel::Geometry::Format& format)
{
switch (format.type)
@@ -841,76 +761,27 @@ static GLenum get_primitive_mode(const GLModel::Geometry::Format& format)
}
}
-static GLenum get_index_type(const GLModel::Geometry::Format& format)
+static GLenum get_index_type(const GLModel::Geometry& data)
{
- switch (format.index_type)
+ switch (data.index_type)
{
default:
case GLModel::Geometry::EIndexType::UINT: { return GL_UNSIGNED_INT; }
case GLModel::Geometry::EIndexType::USHORT: { return GL_UNSIGNED_SHORT; }
+ case GLModel::Geometry::EIndexType::UBYTE: { return GL_UNSIGNED_BYTE; }
}
}
void GLModel::render()
#else
void GLModel::render() const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
render(std::make_pair(0, indices_count()));
#else
GLShaderProgram* shader = wxGetApp().get_current_shader();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- if (shader == nullptr)
- return;
-
- // sends data to gpu if not done yet
- if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) {
- if (m_render_data.geometry.vertices_count() > 0 && m_render_data.geometry.indices_count() > 0 && !send_to_gpu())
- return;
- }
-
- const Geometry& data = m_render_data.geometry;
-
- const GLenum mode = get_primitive_mode(data.format);
- const GLenum index_type = get_index_type(data.format);
-
- const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format);
- const bool position = Geometry::has_position(data.format);
- const bool normal = Geometry::has_normal(data.format);
- const bool tex_coord = Geometry::has_tex_coord(data.format);
-
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
-
- if (position) {
- glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format)));
- glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
- }
- if (normal) {
- glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format)));
- glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
- }
- if (tex_coord) {
- glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format)));
- glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
- }
-
- shader->set_uniform("uniform_color", data.color);
-
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
- glsafe(::glDrawElements(mode, indices_count(), index_type, nullptr));
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
-
- if (tex_coord)
- glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
- if (normal)
- glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
- if (position)
- glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
-
- glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
-#else
for (const RenderData& data : m_render_data) {
if (data.vbo_id == 0 || data.ibo_id == 0)
continue;
@@ -946,11 +817,10 @@ void GLModel::render() const
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::render(const std::pair& range)
{
if (m_render_disabled)
@@ -960,7 +830,6 @@ void GLModel::render(const std::pair& range)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
-
if (shader == nullptr)
return;
@@ -973,7 +842,7 @@ void GLModel::render(const std::pair& range)
const Geometry& data = m_render_data.geometry;
const GLenum mode = get_primitive_mode(data.format);
- const GLenum index_type = get_index_type(data.format);
+ const GLenum index_type = get_index_type(data);
const size_t vertex_stride_bytes = Geometry::vertex_stride_bytes(data.format);
const bool position = Geometry::has_position(data.format);
@@ -982,59 +851,106 @@ void GLModel::render(const std::pair& range)
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ int position_id = -1;
+ int normal_id = -1;
+ int tex_coord_id = -1;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
if (position) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ position_id = shader->get_attrib_location("v_position");
+ if (position_id != -1) {
+ glsafe(::glVertexAttribPointer(position_id, Geometry::position_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::position_offset_bytes(data.format)));
+ glsafe(::glEnableVertexAttribArray(position_id));
+ }
+#else
glsafe(::glVertexPointer(Geometry::position_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::position_offset_bytes(data.format)));
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
if (normal) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ normal_id = shader->get_attrib_location("v_normal");
+ if (normal_id != -1) {
+ glsafe(::glVertexAttribPointer(normal_id, Geometry::normal_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::normal_offset_bytes(data.format)));
+ glsafe(::glEnableVertexAttribArray(normal_id));
+ }
+#else
glsafe(::glNormalPointer(GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::normal_offset_bytes(data.format)));
glsafe(::glEnableClientState(GL_NORMAL_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
if (tex_coord) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ tex_coord_id = shader->get_attrib_location("v_tex_coord");
+ if (tex_coord_id != -1) {
+ glsafe(::glVertexAttribPointer(tex_coord_id, Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, GL_FALSE, vertex_stride_bytes, (GLvoid*)Geometry::tex_coord_offset_bytes(data.format)));
+ glsafe(::glEnableVertexAttribArray(tex_coord_id));
+ }
+#else
glsafe(::glTexCoordPointer(Geometry::tex_coord_stride_floats(data.format), GL_FLOAT, vertex_stride_bytes, (const void*)Geometry::tex_coord_offset_bytes(data.format)));
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
shader->set_uniform("uniform_color", data.color);
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
- glsafe(::glDrawElements(mode, range.second - range.first + 1, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data.format))));
+ glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data))));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (tex_coord_id != -1)
+ glsafe(::glDisableVertexAttribArray(tex_coord_id));
+ if (normal_id != -1)
+ glsafe(::glDisableVertexAttribArray(normal_id));
+ if (position_id != -1)
+ glsafe(::glDisableVertexAttribArray(position_id));
+#else
if (tex_coord)
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
if (normal)
glsafe(::glDisableClientState(GL_NORMAL_ARRAY));
if (position)
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
-}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_GLMODEL_STATISTICS
+ ++s_statistics.render_calls;
+#endif // ENABLE_GLMODEL_STATISTICS
+}
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count)
#else
void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instances_count) const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (instances_vbo == 0)
return;
GLShaderProgram* shader = wxGetApp().get_current_shader();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced_attr"))
+#else
if (shader == nullptr || !boost::algorithm::iends_with(shader->get_name(), "_instanced"))
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return;
// vertex attributes
- GLint position_id = shader->get_attrib_location("v_position");
- GLint normal_id = shader->get_attrib_location("v_normal");
+ const GLint position_id = shader->get_attrib_location("v_position");
+ const GLint normal_id = shader->get_attrib_location("v_normal");
if (position_id == -1 || normal_id == -1)
return;
// instance attributes
- GLint offset_id = shader->get_attrib_location("i_offset");
- GLint scales_id = shader->get_attrib_location("i_scales");
+ const GLint offset_id = shader->get_attrib_location("i_offset");
+ const GLint scales_id = shader->get_attrib_location("i_scales");
if (offset_id == -1 || scales_id == -1)
return;
@@ -1054,10 +970,10 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
GLint offset_id = (shader != nullptr) ? shader->get_attrib_location("i_offset") : -1;
GLint scales_id = (shader != nullptr) ? shader->get_attrib_location("i_scales") : -1;
assert(offset_id != -1 && scales_id != -1);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glVertexAttribPointer(offset_id, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)0));
glsafe(::glEnableVertexAttribArray(offset_id));
glsafe(::glVertexAttribDivisor(offset_id, 1));
@@ -1076,13 +992,13 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glEnableVertexAttribArray(scales_id));
glsafe(::glVertexAttribDivisor(scales_id, 1));
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
const Geometry& data = m_render_data.geometry;
- GLenum mode = get_primitive_mode(data.format);
- GLenum index_type = get_index_type(data.format);
+ const GLenum mode = get_primitive_mode(data.format);
+ const GLenum index_type = get_index_type(data);
shader->set_uniform("uniform_color", data.color);
@@ -1157,12 +1073,16 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
glsafe(::glDisableVertexAttribArray(scales_id));
if (offset_id != -1)
glsafe(::glDisableVertexAttribArray(offset_id));
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
+
+#if ENABLE_GLMODEL_STATISTICS
+ ++s_statistics.render_instanced_calls;
+#endif // ENABLE_GLMODEL_STATISTICS
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool GLModel::send_to_gpu()
{
if (m_render_data.vbo_id > 0 || m_render_data.ibo_id > 0) {
@@ -1182,18 +1102,110 @@ bool GLModel::send_to_gpu()
glsafe(::glBufferData(GL_ARRAY_BUFFER, data.vertices_size_bytes(), data.vertices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
m_render_data.vertices_count = vertices_count();
+#if ENABLE_GLMODEL_STATISTICS
+ s_statistics.gpu_memory.vertices.current += data.vertices_size_bytes();
+ s_statistics.gpu_memory.vertices.max = std::max(s_statistics.gpu_memory.vertices.current, s_statistics.gpu_memory.vertices.max);
+#endif // ENABLE_GLMODEL_STATISTICS
data.vertices = std::vector();
// indices
glsafe(::glGenBuffers(1, &m_render_data.ibo_id));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id));
- glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW));
- glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
- m_render_data.indices_count = indices_count();
- data.indices = std::vector();
+ const size_t indices_count = data.indices.size();
+ if (m_render_data.vertices_count <= 256) {
+ // convert indices to unsigned char to save gpu memory
+ std::vector reduced_indices(indices_count);
+ for (size_t i = 0; i < indices_count; ++i) {
+ reduced_indices[i] = (unsigned char)data.indices[i];
+ }
+ data.index_type = Geometry::EIndexType::UBYTE;
+ glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_count * sizeof(unsigned char), reduced_indices.data(), GL_STATIC_DRAW));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
+ else if (m_render_data.vertices_count <= 65536) {
+ // convert indices to unsigned short to save gpu memory
+ std::vector reduced_indices(indices_count);
+ for (size_t i = 0; i < data.indices.size(); ++i) {
+ reduced_indices[i] = (unsigned short)data.indices[i];
+ }
+ data.index_type = Geometry::EIndexType::USHORT;
+ glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_count * sizeof(unsigned short), reduced_indices.data(), GL_STATIC_DRAW));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
+ else {
+ glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW));
+ glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ }
+ m_render_data.indices_count = indices_count;
+#if ENABLE_GLMODEL_STATISTICS
+ s_statistics.gpu_memory.indices.current += data.indices_size_bytes();
+ s_statistics.gpu_memory.indices.max = std::max(s_statistics.gpu_memory.indices.current, s_statistics.gpu_memory.indices.max);
+#endif // ENABLE_GLMODEL_STATISTICS
+ data.indices = std::vector();
return true;
}
+
+#if ENABLE_GLMODEL_STATISTICS
+void GLModel::render_statistics()
+{
+ static const float offset = 175.0f;
+ ImGuiWrapper& imgui = *wxGetApp().imgui();
+
+ auto add_memory = [&imgui](const std::string& label, int64_t memory) {
+ auto format_string = [memory](const std::string& units, float value) {
+ return std::to_string(memory) + " bytes (" +
+ Slic3r::float_to_string_decimal_point(float(memory) * value, 3)
+ + " " + units + ")";
+ };
+
+ static const float kb = 1024.0f;
+ static const float inv_kb = 1.0f / kb;
+ static const float mb = 1024.0f * kb;
+ static const float inv_mb = 1.0f / mb;
+ static const float gb = 1024.0f * mb;
+ static const float inv_gb = 1.0f / gb;
+ imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
+ ImGui::SameLine(offset);
+ if (static_cast(memory) < mb)
+ imgui.text(format_string("KB", inv_kb));
+ else if (static_cast(memory) < gb)
+ imgui.text(format_string("MB", inv_mb));
+ else
+ imgui.text(format_string("GB", inv_gb));
+ };
+
+ auto add_counter = [&imgui](const std::string& label, int64_t counter) {
+ imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
+ ImGui::SameLine(offset);
+ imgui.text(std::to_string(counter));
+ };
+
+ imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f);
+ ImGui::SetNextWindowSizeConstraints({ 300.0f, 100.0f }, { 600.0f, 900.0f });
+ imgui.begin(std::string("GLModel Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
+ ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
+
+ add_counter(std::string("Render calls:"), s_statistics.render_calls);
+ add_counter(std::string("Render instanced calls:"), s_statistics.render_instanced_calls);
+
+ if (ImGui::CollapsingHeader("GPU memory")) {
+ ImGui::Indent(10.0f);
+ if (ImGui::CollapsingHeader("Vertices")) {
+ add_memory(std::string("Current:"), s_statistics.gpu_memory.vertices.current);
+ add_memory(std::string("Max:"), s_statistics.gpu_memory.vertices.max);
+ }
+ if (ImGui::CollapsingHeader("Indices")) {
+ add_memory(std::string("Current:"), s_statistics.gpu_memory.indices.current);
+ add_memory(std::string("Max:"), s_statistics.gpu_memory.indices.max);
+ }
+ ImGui::Unindent(10.0f);
+ }
+
+ imgui.end();
+}
+#endif // ENABLE_GLMODEL_STATISTICS
+
#else
void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices)
{
@@ -1212,23 +1224,9 @@ void GLModel::send_to_gpu(RenderData& data, const std::vector& vertices,
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW));
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
-static void append_vertex(GLModel::Geometry& data, const Vec3f& position, const Vec3f& normal)
-{
- data.add_vertex(position, normal);
-}
-
-static void append_triangle(GLModel::Geometry& data, unsigned short v1, unsigned short v2, unsigned short v3)
-{
- data.add_ushort_index(v1);
- data.add_ushort_index(v2);
- data.add_ushort_index(v3);
-}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
-
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
template
inline bool all_vertices_inside(const GLModel::Geometry& geometry, Fn fn)
{
@@ -1282,11 +1280,11 @@ bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_botto
return true;
}
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
+GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height)
{
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
@@ -1296,28 +1294,25 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
- resolution = std::max(4, resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- resolution = std::min(10922, resolution); // ensure no unsigned short overflow of indices
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+ resolution = std::max(4, resolution);
GLModel::Geometry data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(6 * resolution + 2);
data.reserve_indices(6 * resolution * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float angle_step = 2.0f * float(PI) / float(resolution);
std::vector cosines(resolution);
std::vector sines(resolution);
- for (unsigned short i = 0; i < resolution; ++i) {
+ for (unsigned int i = 0; i < resolution; ++i) {
const float angle = angle_step * float(i);
cosines[i] = ::cos(angle);
sines[i] = -::sin(angle);
@@ -1326,64 +1321,64 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl
const float total_height = tip_height + stem_height;
// tip vertices/normals
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- append_vertex(data, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ());
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ data.add_vertex(Vec3f(0.0f, 0.0f, total_height), (Vec3f)Vec3f::UnitZ());
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(tip_radius * sines[i], tip_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f));
}
// tip triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short v3 = (i < resolution - 1) ? i + 2 : 1;
- append_triangle(data, 0, i + 1, v3);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int v3 = (i < resolution - 1) ? i + 2 : 1;
+ data.add_triangle(0, i + 1, v3);
}
// tip cap outer perimeter vertices
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { tip_radius * sines[i], tip_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(tip_radius * sines[i], tip_radius * cosines[i], stem_height), (Vec3f)(-Vec3f::UnitZ()));
}
// tip cap inner perimeter vertices
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, -Vec3f::UnitZ());
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), (Vec3f)(-Vec3f::UnitZ()));
}
// tip cap triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1;
- const unsigned short v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1;
- append_triangle(data, i + resolution + 1, v3, v2);
- append_triangle(data, i + resolution + 1, i + 2 * resolution + 1, v3);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int v2 = (i < resolution - 1) ? i + resolution + 2 : resolution + 1;
+ const unsigned int v3 = (i < resolution - 1) ? i + 2 * resolution + 2 : 2 * resolution + 1;
+ data.add_triangle(i + resolution + 1, v3, v2);
+ data.add_triangle(i + resolution + 1, i + 2 * resolution + 1, v3);
}
// stem bottom vertices
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], stem_height }, { sines[i], cosines[i], 0.0f });
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], stem_height), Vec3f(sines[i], cosines[i], 0.0f));
}
// stem top vertices
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, { sines[i], cosines[i], 0.0f });
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), Vec3f(sines[i], cosines[i], 0.0f));
}
// stem triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
- const unsigned short v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
- append_triangle(data, i + 3 * resolution + 1, v3, v2);
- append_triangle(data, i + 3 * resolution + 1, i + 4 * resolution + 1, v3);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int v2 = (i < resolution - 1) ? i + 3 * resolution + 2 : 3 * resolution + 1;
+ const unsigned int v3 = (i < resolution - 1) ? i + 4 * resolution + 2 : 4 * resolution + 1;
+ data.add_triangle(i + 3 * resolution + 1, v3, v2);
+ data.add_triangle(i + 3 * resolution + 1, i + 4 * resolution + 1, v3);
}
// stem cap vertices
- append_vertex(data, Vec3f::Zero(), -Vec3f::UnitZ());
- for (unsigned short i = 0; i < resolution; ++i) {
- append_vertex(data, { stem_radius * sines[i], stem_radius * cosines[i], 0.0f }, -Vec3f::UnitZ());
+ data.add_vertex((Vec3f)Vec3f::Zero(), (Vec3f)(-Vec3f::UnitZ()));
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_vertex(Vec3f(stem_radius * sines[i], stem_radius * cosines[i], 0.0f), (Vec3f)(-Vec3f::UnitZ()));
}
// stem cap triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
- append_triangle(data, 5 * resolution + 1, v3, i + 5 * resolution + 2);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int v3 = (i < resolution - 1) ? i + 5 * resolution + 3 : 5 * resolution + 2;
+ data.add_triangle(5 * resolution + 1, v3, i + 5 * resolution + 2);
}
#else
append_vertex(entity, { 0.0f, 0.0f, total_height }, Vec3f::UnitZ());
@@ -1446,14 +1441,14 @@ GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, fl
}
data.entities.emplace_back(entity);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
-GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
+GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness)
{
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
@@ -1463,22 +1458,19 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
- resolution = std::max(2, resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- resolution = std::min(8188, resolution); // ensure no unsigned short overflow of indices
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+ resolution = std::max(2, resolution);
GLModel::Geometry data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(8 * (resolution + 1) + 30);
data.reserve_indices((8 * resolution + 16) * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float half_thickness = 0.5f * thickness;
const float half_stem_width = 0.5f * stem_width;
@@ -1488,149 +1480,149 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float
const float inner_radius = radius - half_stem_width;
const float step_angle = 0.5f * float(PI) / float(resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// tip
// top face vertices
- append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { -tip_height, radius, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(-tip_height, radius, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitZ());
// top face triangles
- append_triangle(data, 0, 1, 2);
- append_triangle(data, 0, 2, 4);
- append_triangle(data, 4, 2, 3);
+ data.add_triangle(0, 1, 2);
+ data.add_triangle(0, 2, 4);
+ data.add_triangle(4, 2, 3);
// bottom face vertices
- append_vertex(data, { 0.0f, outer_radius, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { -tip_height, radius, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { 0.0f, inner_radius, -half_thickness }, -Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
// bottom face triangles
- append_triangle(data, 5, 7, 6);
- append_triangle(data, 5, 9, 7);
- append_triangle(data, 9, 8, 7);
+ data.add_triangle(5, 7, 6);
+ data.add_triangle(5, 9, 7);
+ data.add_triangle(9, 8, 7);
// side faces vertices
- append_vertex(data, { 0.0f, outer_radius, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, outer_radius, half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, outer_radius, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, outer_radius, half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX());
Vec3f normal(-half_tip_width, tip_height, 0.0f);
normal.normalize();
- append_vertex(data, { 0.0f, radius + half_tip_width, -half_thickness }, normal);
- append_vertex(data, { -tip_height, radius, -half_thickness }, normal);
- append_vertex(data, { 0.0f, radius + half_tip_width, half_thickness }, normal);
- append_vertex(data, { -tip_height, radius, half_thickness }, normal);
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, -half_thickness), normal);
+ data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, radius + half_tip_width, half_thickness), normal);
+ data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal);
normal = { -half_tip_width, -tip_height, 0.0f };
normal.normalize();
- append_vertex(data, { -tip_height, radius, -half_thickness }, normal);
- append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, normal);
- append_vertex(data, { -tip_height, radius, half_thickness }, normal);
- append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, normal);
+ data.add_vertex(Vec3f(-tip_height, radius, -half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), normal);
+ data.add_vertex(Vec3f(-tip_height, radius, half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), normal);
- append_vertex(data, { 0.0f, radius - half_tip_width, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, inner_radius, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, radius - half_tip_width, half_thickness }, Vec3f::UnitX());
- append_vertex(data, { 0.0f, inner_radius, half_thickness }, Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, inner_radius, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, radius - half_tip_width, half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(0.0f, inner_radius, half_thickness), (Vec3f)Vec3f::UnitX());
// side face triangles
- for (unsigned short i = 0; i < 4; ++i) {
- const unsigned short ii = i * 4;
- append_triangle(data, 10 + ii, 11 + ii, 13 + ii);
- append_triangle(data, 10 + ii, 13 + ii, 12 + ii);
+ for (unsigned int i = 0; i < 4; ++i) {
+ const unsigned int ii = i * 4;
+ data.add_triangle(10 + ii, 11 + ii, 13 + ii);
+ data.add_triangle(10 + ii, 13 + ii, 12 + ii);
}
// stem
// top face vertices
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
- append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
+ data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ());
}
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
- append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness }, Vec3f::UnitZ());
+ data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), half_thickness), (Vec3f)Vec3f::UnitZ());
}
// top face triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- append_triangle(data, 26 + i, 27 + i, 27 + resolution + i);
- append_triangle(data, 27 + i, 28 + resolution + i, 27 + resolution + i);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_triangle(26 + i, 27 + i, 27 + resolution + i);
+ data.add_triangle(27 + i, 28 + resolution + i, 27 + resolution + i);
}
// bottom face vertices
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
- append_vertex(data, { inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
+ data.add_vertex(Vec3f(inner_radius * ::sin(angle), inner_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
}
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
- append_vertex(data, { outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness }, -Vec3f::UnitZ());
+ data.add_vertex(Vec3f(outer_radius * ::sin(angle), outer_radius * ::cos(angle), -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
}
// bottom face triangles
- for (unsigned short i = 0; i < resolution; ++i) {
- append_triangle(data, 28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i);
- append_triangle(data, 29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_triangle(28 + 2 * resolution + i, 29 + 3 * resolution + i, 29 + 2 * resolution + i);
+ data.add_triangle(29 + 2 * resolution + i, 29 + 3 * resolution + i, 30 + 3 * resolution + i);
}
// side faces vertices and triangles
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
- append_vertex(data, { inner_radius * s, inner_radius * c, -half_thickness }, { -s, -c, 0.0f });
+ data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, -half_thickness), Vec3f(-s, -c, 0.0f));
}
- for (unsigned short i = 0; i <= resolution; ++i) {
+ for (unsigned int i = 0; i <= resolution; ++i) {
const float angle = float(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
- append_vertex(data, { inner_radius * s, inner_radius * c, half_thickness }, { -s, -c, 0.0f });
+ data.add_vertex(Vec3f(inner_radius * s, inner_radius * c, half_thickness), Vec3f(-s, -c, 0.0f));
}
- unsigned short first_id = 26 + 4 * (resolution + 1);
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short ii = first_id + i;
- append_triangle(data, ii, ii + 1, ii + resolution + 2);
- append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1);
+ unsigned int first_id = 26 + 4 * (resolution + 1);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int ii = first_id + i;
+ data.add_triangle(ii, ii + 1, ii + resolution + 2);
+ data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1);
}
- append_vertex(data, { inner_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { outer_radius, 0.0f, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { inner_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { outer_radius, 0.0f, half_thickness }, -Vec3f::UnitY());
+ data.add_vertex(Vec3f(inner_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(outer_radius, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(inner_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(outer_radius, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
first_id = 26 + 6 * (resolution + 1);
- append_triangle(data, first_id, first_id + 1, first_id + 3);
- append_triangle(data, first_id, first_id + 3, first_id + 2);
+ data.add_triangle(first_id, first_id + 1, first_id + 3);
+ data.add_triangle(first_id, first_id + 3, first_id + 2);
- for (short i = resolution; i >= 0; --i) {
+ for (int i = resolution; i >= 0; --i) {
const float angle = float(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
- append_vertex(data, { outer_radius * s, outer_radius * c, -half_thickness }, { s, c, 0.0f });
+ data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, -half_thickness), Vec3f(s, c, 0.0f));
}
- for (short i = resolution; i >= 0; --i) {
+ for (int i = resolution; i >= 0; --i) {
const float angle = float(i) * step_angle;
const float c = ::cos(angle);
const float s = ::sin(angle);
- append_vertex(data, { outer_radius * s, outer_radius * c, +half_thickness }, { s, c, 0.0f });
+ data.add_vertex(Vec3f(outer_radius * s, outer_radius * c, +half_thickness), Vec3f(s, c, 0.0f));
}
first_id = 30 + 6 * (resolution + 1);
- for (unsigned short i = 0; i < resolution; ++i) {
- const unsigned short ii = first_id + i;
- append_triangle(data, ii, ii + 1, ii + resolution + 2);
- append_triangle(data, ii, ii + resolution + 2, ii + resolution + 1);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ const unsigned int ii = first_id + i;
+ data.add_triangle(ii, ii + 1, ii + resolution + 2);
+ data.add_triangle(ii, ii + resolution + 2, ii + resolution + 1);
}
#else
// tip
@@ -1778,14 +1770,14 @@ GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float
}
data.entities.emplace_back(entity);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_width, float stem_height, float thickness)
{
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
auto append_vertex = [](GLModel::Geometry::Entity& entity, const Vec3f& position, const Vec3f& normal) {
entity.positions.emplace_back(position);
entity.normals.emplace_back(normal);
@@ -1795,101 +1787,101 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w
entity.indices.emplace_back(v2);
entity.indices.emplace_back(v3);
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(42);
data.reserve_indices(72);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float half_thickness = 0.5f * thickness;
const float half_stem_width = 0.5f * stem_width;
const float half_tip_width = 0.5f * tip_width;
const float total_height = tip_height + stem_height;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// top face vertices
- append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { 0.0, total_height, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { -half_tip_width, stem_height, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { -half_stem_width, stem_height, half_thickness }, Vec3f::UnitZ());
- append_vertex(data, { -half_stem_width, 0.0, half_thickness }, Vec3f::UnitZ());
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(0.0f, total_height, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitZ());
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitZ());
// top face triangles
- append_triangle(data, 0, 1, 6);
- append_triangle(data, 6, 1, 5);
- append_triangle(data, 4, 5, 3);
- append_triangle(data, 5, 1, 3);
- append_triangle(data, 1, 2, 3);
+ data.add_triangle(0, 1, 6);
+ data.add_triangle(6, 1, 5);
+ data.add_triangle(4, 5, 3);
+ data.add_triangle(5, 1, 3);
+ data.add_triangle(1, 2, 3);
// bottom face vertices
- append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { 0.0, total_height, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitZ());
- append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitZ());
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitZ()));
// bottom face triangles
- append_triangle(data, 7, 13, 8);
- append_triangle(data, 13, 12, 8);
- append_triangle(data, 12, 11, 10);
- append_triangle(data, 8, 12, 10);
- append_triangle(data, 9, 8, 10);
+ data.add_triangle(7, 13, 8);
+ data.add_triangle(13, 12, 8);
+ data.add_triangle(12, 11, 10);
+ data.add_triangle(8, 12, 10);
+ data.add_triangle(9, 8, 10);
// side faces vertices
- append_vertex(data, { half_stem_width, 0.0, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { half_stem_width, stem_height, -half_thickness }, Vec3f::UnitX());
- append_vertex(data, { half_stem_width, 0.0, half_thickness }, Vec3f::UnitX());
- append_vertex(data, { half_stem_width, stem_height, half_thickness }, Vec3f::UnitX());
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)Vec3f::UnitX());
+ data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)Vec3f::UnitX());
- append_vertex(data, { half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
+ data.add_vertex(Vec3f(half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
Vec3f normal(tip_height, half_tip_width, 0.0f);
normal.normalize();
- append_vertex(data, { half_tip_width, stem_height, -half_thickness }, normal);
- append_vertex(data, { 0.0, total_height, -half_thickness }, normal);
- append_vertex(data, { half_tip_width, stem_height, half_thickness }, normal);
- append_vertex(data, { 0.0, total_height, half_thickness }, normal);
+ data.add_vertex(Vec3f(half_tip_width, stem_height, -half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal);
+ data.add_vertex(Vec3f(half_tip_width, stem_height, half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal);
normal = { -tip_height, half_tip_width, 0.0f };
normal.normalize();
- append_vertex(data, { 0.0, total_height, -half_thickness }, normal);
- append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, normal);
- append_vertex(data, { 0.0, total_height, half_thickness }, normal);
- append_vertex(data, { -half_tip_width, stem_height, half_thickness }, normal);
+ data.add_vertex(Vec3f(0.0f, total_height, -half_thickness), normal);
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), normal);
+ data.add_vertex(Vec3f(0.0f, total_height, half_thickness), normal);
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), normal);
- append_vertex(data, { -half_tip_width, stem_height, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { -half_tip_width, stem_height, half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitY());
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(-half_tip_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitY()));
- append_vertex(data, { -half_stem_width, stem_height, -half_thickness }, -Vec3f::UnitX());
- append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitX());
- append_vertex(data, { -half_stem_width, stem_height, half_thickness }, -Vec3f::UnitX());
- append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitX());
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, -half_thickness), (Vec3f)(-Vec3f::UnitX()));
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitX()));
+ data.add_vertex(Vec3f(-half_stem_width, stem_height, half_thickness), (Vec3f)(-Vec3f::UnitX()));
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitX()));
- append_vertex(data, { -half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { half_stem_width, 0.0, -half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { -half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
- append_vertex(data, { half_stem_width, 0.0, half_thickness }, -Vec3f::UnitY());
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, -half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(-half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
+ data.add_vertex(Vec3f(half_stem_width, 0.0f, half_thickness), (Vec3f)(-Vec3f::UnitY()));
// side face triangles
- for (unsigned short i = 0; i < 7; ++i) {
- const unsigned short ii = i * 4;
- append_triangle(data, 14 + ii, 15 + ii, 17 + ii);
- append_triangle(data, 14 + ii, 17 + ii, 16 + ii);
+ for (unsigned int i = 0; i < 7; ++i) {
+ const unsigned int ii = i * 4;
+ data.add_triangle(14 + ii, 15 + ii, 17 + ii);
+ data.add_triangle(14 + ii, 17 + ii, 16 + ii);
}
#else
// top face vertices
@@ -1972,54 +1964,51 @@ GLModel::Geometry straight_arrow(float tip_width, float tip_height, float stem_w
}
data.entities.emplace_back(entity);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
-GLModel::Geometry diamond(unsigned short resolution)
+GLModel::Geometry diamond(unsigned int resolution)
{
- resolution = std::max(4, resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- resolution = std::min(65534, resolution); // ensure no unsigned short overflow of indices
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+ resolution = std::max(4, resolution);
GLModel::Geometry data;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices(resolution + 2);
data.reserve_indices((2 * (resolution + 1)) * 3);
#else
GLModel::Geometry::Entity entity;
entity.type = GLModel::EPrimitiveType::Triangles;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float step = 2.0f * float(PI) / float(resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// vertices
- for (unsigned short i = 0; i < resolution; ++i) {
+ for (unsigned int i = 0; i < resolution; ++i) {
const float ii = float(i) * step;
const Vec3f p = { 0.5f * ::cos(ii), 0.5f * ::sin(ii), 0.0f };
- append_vertex(data, p, p.normalized());
+ data.add_vertex(p, (Vec3f)p.normalized());
}
Vec3f p = { 0.0f, 0.0f, 0.5f };
- append_vertex(data, p, p.normalized());
+ data.add_vertex(p, (Vec3f)p.normalized());
p = { 0.0f, 0.0f, -0.5f };
- append_vertex(data, p, p.normalized());
+ data.add_vertex(p, (Vec3f)p.normalized());
// triangles
// top
- for (unsigned short i = 0; i < resolution; ++i) {
- append_triangle(data, i + 0, i + 1, resolution);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_triangle(i + 0, i + 1, resolution);
}
- append_triangle(data, resolution - 1, 0, resolution);
+ data.add_triangle(resolution - 1, 0, resolution);
// bottom
- for (unsigned short i = 0; i < resolution; ++i) {
- append_triangle(data, i + 0, resolution + 1, i + 1);
+ for (unsigned int i = 0; i < resolution; ++i) {
+ data.add_triangle(i + 0, resolution + 1, i + 1);
}
- append_triangle(data, resolution - 1, resolution + 1, 0);
+ data.add_triangle(resolution - 1, resolution + 1, 0);
#else
// positions
for (int i = 0; i < resolution; ++i) {
@@ -2056,31 +2045,30 @@ GLModel::Geometry diamond(unsigned short resolution)
entity.indices.push_back(0);
data.entities.emplace_back(entity);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
return data;
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SHOW_TOOLPATHS_COG
-GLModel::Geometry smooth_sphere(unsigned short resolution, float radius)
+GLModel::Geometry smooth_sphere(unsigned int resolution, float radius)
{
- resolution = std::max(4, resolution);
- resolution = std::min(256, resolution); // ensure no unsigned short overflow of indices
+ resolution = std::max(4, resolution);
- const unsigned short sectorCount = /*2 **/ resolution;
- const unsigned short stackCount = resolution;
+ const unsigned int sectorCount = resolution;
+ const unsigned int stackCount = resolution;
const float sectorStep = float(2.0 * M_PI / sectorCount);
const float stackStep = float(M_PI / stackCount);
GLModel::Geometry data;
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::USHORT };
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
data.reserve_vertices((stackCount - 1) * sectorCount + 2);
data.reserve_indices((2 * (stackCount - 1) * sectorCount) * 3);
// vertices
- for (unsigned short i = 0; i <= stackCount; ++i) {
+ for (unsigned int i = 0; i <= stackCount; ++i) {
// from pi/2 to -pi/2
const double stackAngle = 0.5 * M_PI - stackStep * i;
const double xy = double(radius) * ::cos(stackAngle);
@@ -2090,7 +2078,7 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius)
data.add_vertex(v, (Vec3f)v.normalized());
}
else {
- for (unsigned short j = 0; j < sectorCount; ++j) {
+ for (unsigned int j = 0; j < sectorCount; ++j) {
// from 0 to 2pi
const double sectorAngle = sectorStep * j;
const Vec3f v(float(xy * std::cos(sectorAngle)), float(xy * std::sin(sectorAngle)), float(z));
@@ -2100,24 +2088,24 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius)
}
// triangles
- for (unsigned short i = 0; i < stackCount; ++i) {
+ for (unsigned int i = 0; i < stackCount; ++i) {
// Beginning of current stack.
- unsigned short k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount);
- const unsigned short k1_first = k1;
+ unsigned int k1 = (i == 0) ? 0 : (1 + (i - 1) * sectorCount);
+ const unsigned int k1_first = k1;
// Beginning of next stack.
- unsigned short k2 = (i == 0) ? 1 : (k1 + sectorCount);
- const unsigned short k2_first = k2;
- for (unsigned short j = 0; j < sectorCount; ++j) {
+ unsigned int k2 = (i == 0) ? 1 : (k1 + sectorCount);
+ const unsigned int k2_first = k2;
+ for (unsigned int j = 0; j < sectorCount; ++j) {
// 2 triangles per sector excluding first and last stacks
- unsigned short k1_next = k1;
- unsigned short k2_next = k2;
+ unsigned int k1_next = k1;
+ unsigned int k2_next = k2;
if (i != 0) {
k1_next = (j + 1 == sectorCount) ? k1_first : (k1 + 1);
- data.add_ushort_triangle(k1, k2, k1_next);
+ data.add_triangle(k1, k2, k1_next);
}
if (i + 1 != stackCount) {
k2_next = (j + 1 == sectorCount) ? k2_first : (k2 + 1);
- data.add_ushort_triangle(k1_next, k2, k2_next);
+ data.add_triangle(k1_next, k2, k2_next);
}
k1 = k1_next;
k2 = k2_next;
@@ -2127,7 +2115,7 @@ GLModel::Geometry smooth_sphere(unsigned short resolution, float radius)
return data;
}
#endif // ENABLE_SHOW_TOOLPATHS_COG
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace GUI
} // namespace Slic3r
diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp
index 3b268dab7..e2da09484 100644
--- a/src/slic3r/GUI/GLModel.hpp
+++ b/src/slic3r/GUI/GLModel.hpp
@@ -14,16 +14,16 @@ namespace Slic3r {
class TriangleMesh;
class Polygon;
using Polygons = std::vector;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
class BuildVolume;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
namespace GUI {
class GLModel
{
public:
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
enum class EPrimitiveType : unsigned char
{
Triangles,
@@ -40,11 +40,11 @@ namespace GUI {
size_t indices_count{ 0 };
ColorRGBA color;
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
struct Geometry
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
enum class EPrimitiveType : unsigned char
{
Points,
@@ -68,23 +68,25 @@ namespace GUI {
enum class EIndexType : unsigned char
{
UINT, // unsigned int
- USHORT // unsigned short
+ USHORT, // unsigned short
+ UBYTE // unsigned byte
};
struct Format
{
EPrimitiveType type{ EPrimitiveType::Triangles };
EVertexLayout vertex_layout{ EVertexLayout::P3N3 };
- EIndexType index_type{ EIndexType::UINT };
};
Format format;
std::vector vertices;
- std::vector indices;
+ std::vector indices;
+ EIndexType index_type{ EIndexType::UINT };
ColorRGBA color{ ColorRGBA::BLACK() };
- void reserve_vertices(size_t vertices_count);
- void reserve_indices(size_t indices_count);
+ void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); }
+ void reserve_indices(size_t indices_count) { indices.reserve(indices_count * index_stride_bytes(*this)); }
+
void add_vertex(const Vec2f& position); // EVertexLayout::P2
void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2
@@ -92,42 +94,31 @@ namespace GUI {
void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2
void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3
- void set_ushort_index(size_t id, unsigned short index);
- void set_uint_index(size_t id, unsigned int index);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+ void set_index(size_t id, unsigned int index);
- void add_ushort_index(unsigned short id);
- void add_uint_index(unsigned int id);
-
- void add_ushort_line(unsigned short id1, unsigned short id2);
- void add_uint_line(unsigned int id1, unsigned int id2);
-
- void add_ushort_triangle(unsigned short id1, unsigned short id2, unsigned short id3);
- void add_uint_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
+ void add_index(unsigned int id);
+ void add_line(unsigned int id1, unsigned int id2);
+ void add_triangle(unsigned int id1, unsigned int id2, unsigned int id3);
Vec2f extract_position_2(size_t id) const;
Vec3f extract_position_3(size_t id) const;
Vec3f extract_normal_3(size_t id) const;
Vec2f extract_tex_coord_2(size_t id) const;
- unsigned int extract_uint_index(size_t id) const;
- unsigned short extract_ushort_index(size_t id) const;
+ unsigned int extract_index(size_t id) const;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
void remove_vertex(size_t id);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
bool is_empty() const { return vertices_count() == 0 || indices_count() == 0; }
size_t vertices_count() const { return vertices.size() / vertex_stride_floats(format); }
- size_t indices_count() const { return indices.size() / index_stride_bytes(format); }
+ size_t indices_count() const { return indices.size(); }
size_t vertices_size_floats() const { return vertices.size(); }
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
- size_t indices_size_bytes() const { return indices.size(); }
+ size_t indices_size_bytes() const { return indices.size() * index_stride_bytes(*this); }
static size_t vertex_stride_floats(const Format& format);
static size_t vertex_stride_bytes(const Format& format) { return vertex_stride_floats(format) * sizeof(float); }
@@ -147,9 +138,7 @@ namespace GUI {
static size_t tex_coord_offset_floats(const Format& format);
static size_t tex_coord_offset_bytes(const Format& format) { return tex_coord_offset_floats(format) * sizeof(float); }
- static size_t index_stride_bytes(const Format& format);
-
- static EIndexType index_type(size_t vertices_count);
+ static size_t index_stride_bytes(const Geometry& data);
static bool has_position(const Format& format);
static bool has_normal(const Format& format);
@@ -172,10 +161,10 @@ namespace GUI {
size_t indices_count() const;
size_t indices_size_bytes() const { return indices_count() * sizeof(unsigned int); }
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
struct RenderData
{
Geometry geometry;
@@ -184,16 +173,35 @@ namespace GUI {
size_t vertices_count{ 0 };
size_t indices_count{ 0 };
};
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- RenderData m_render_data;
-#else
- std::vector m_render_data;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GLMODEL_STATISTICS
+ struct Statistics
+ {
+ struct Buffers
+ {
+ struct Data
+ {
+ size_t current{ 0 };
+ size_t max{ 0 };
+ };
+ Data indices;
+ Data vertices;
+ };
+
+ Buffers gpu_memory;
+
+ int64_t render_calls{ 0 };
+ int64_t render_instanced_calls{ 0 };
+ };
+
+ static Statistics s_statistics;
+#endif // ENABLE_GLMODEL_STATISTICS
+
+ RenderData m_render_data;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
// By default the vertex and index buffers data are sent to gpu at the first call to render() method.
// If you need to initialize a model from outside the main thread, so that a call to render() may happen
// before the initialization is complete, use the methods:
@@ -202,7 +210,9 @@ namespace GUI {
// enable_render()
// to keep the data on cpu side until needed.
bool m_render_disabled{ false };
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#else
+ std::vector m_render_data;
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
BoundingBoxf3 m_bounding_box;
std::string m_filename;
@@ -210,7 +220,7 @@ namespace GUI {
GLModel() = default;
virtual ~GLModel() { reset(); }
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
size_t vertices_count() const { return m_render_data.vertices_count > 0 ?
m_render_data.vertices_count : m_render_data.geometry.vertices_count(); }
size_t indices_count() const { return m_render_data.indices_count > 0 ?
@@ -219,11 +229,9 @@ namespace GUI {
size_t vertices_size_floats() const { return vertices_count() * Geometry::vertex_stride_floats(m_render_data.geometry.format); }
size_t vertices_size_bytes() const { return vertices_size_floats() * sizeof(float); }
- size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry.format); }
+ size_t indices_size_bytes() const { return indices_count() * Geometry::index_stride_bytes(m_render_data.geometry); }
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
const Geometry& get_geometry() const { return m_render_data.geometry; }
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
void init_from(Geometry&& data);
#if ENABLE_SMOOTH_NORMALS
@@ -234,43 +242,39 @@ namespace GUI {
#else
void init_from(const Geometry& data);
void init_from(const indexed_triangle_set& its, const BoundingBoxf3& bbox);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void init_from(const indexed_triangle_set& its);
void init_from(const Polygons& polygons, float z);
bool init_from_file(const std::string& filename);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void set_color(const ColorRGBA& color) { m_render_data.geometry.color = color; }
const ColorRGBA& get_color() const { return m_render_data.geometry.color; }
#else
// if entity_id == -1 set the color of all entities
void set_color(int entity_id, const ColorRGBA& color);
ColorRGBA get_color(size_t entity_id = 0U) const;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void reset();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void render();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
void render(const std::pair& range);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
void render_instanced(unsigned int instances_vbo, unsigned int instances_count);
bool is_initialized() const { return vertices_count() > 0 && indices_count() > 0; }
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
bool is_empty() const { return m_render_data.geometry.is_empty(); }
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
#else
void render() const;
void render_instanced(unsigned int instances_vbo, unsigned int instances_count) const;
bool is_initialized() const { return !m_render_data.empty(); }
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const BoundingBoxf3& get_bounding_box() const { return m_bounding_box; }
const std::string& get_filename() const { return m_filename; }
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool is_render_disabled() const { return m_render_disabled; }
void enable_render() { m_render_disabled = false; }
void disable_render() { m_render_disabled = true; }
@@ -291,31 +295,39 @@ namespace GUI {
ret += indices_size_bytes();
return ret;
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+
+#if ENABLE_GLMODEL_STATISTICS
+ static void render_statistics();
+ static void reset_statistics_counters() {
+ s_statistics.render_calls = 0;
+ s_statistics.render_instanced_calls = 0;
+ }
+#endif // ENABLE_GLMODEL_STATISTICS
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
private:
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool send_to_gpu();
#else
void send_to_gpu(RenderData& data, const std::vector& vertices, const std::vector& indices);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool contains(const BuildVolume& volume, const GLModel& model, bool ignore_bottom = true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// create an arrow with cylindrical stem and conical tip, with the given dimensions and resolution
// the origin of the arrow is in the center of the stem cap
// the arrow has its axis of symmetry along the Z axis and is pointing upward
// used to render bed axes and sequential marker
- GLModel::Geometry stilized_arrow(unsigned short resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
+ GLModel::Geometry stilized_arrow(unsigned int resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
// create an arrow whose stem is a quarter of circle, with the given dimensions and resolution
// the origin of the arrow is in the center of the circle
// the arrow is contained in the 1st quadrant of the XY plane and is pointing counterclockwise
// used to render sidebar hints for rotations
- GLModel::Geometry circular_arrow(unsigned short resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
+ GLModel::Geometry circular_arrow(unsigned int resolution, float radius, float tip_height, float tip_width, float stem_width, float thickness);
// create an arrow with the given dimensions
// the origin of the arrow is in the center of the stem cap
@@ -326,15 +338,15 @@ namespace GUI {
// create a diamond with the given resolution
// the origin of the diamond is in its center
// the diamond is contained into a box with size [1, 1, 1]
- GLModel::Geometry diamond(unsigned short resolution);
+ GLModel::Geometry diamond(unsigned int resolution);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SHOW_TOOLPATHS_COG
// create a sphere with the given resolution and smooth normals
// the origin of the sphere is in its center
- GLModel::Geometry smooth_sphere(unsigned short resolution, float radius);
+ GLModel::Geometry smooth_sphere(unsigned int resolution, float radius);
#endif // ENABLE_SHOW_TOOLPATHS_COG
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace GUI
} // namespace Slic3r
diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp
index 86915699d..19327b33a 100644
--- a/src/slic3r/GUI/GLSelectionRectangle.cpp
+++ b/src/slic3r/GUI/GLSelectionRectangle.cpp
@@ -74,34 +74,49 @@ namespace GUI {
if (!is_dragging())
return;
- const Camera& camera = wxGetApp().plater()->get_camera();
- float inv_zoom = (float)camera.get_inv_zoom();
+ const Size cnv_size = canvas.get_canvas_size();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float cnv_width = (float)cnv_size.get_width();
+ const float cnv_height = (float)cnv_size.get_height();
+ if (cnv_width == 0.0f || cnv_height == 0.0f)
+ return;
- Size cnv_size = canvas.get_canvas_size();
- float cnv_half_width = 0.5f * (float)cnv_size.get_width();
- float cnv_half_height = 0.5f * (float)cnv_size.get_height();
+ const float cnv_inv_width = 1.0f / cnv_width;
+ const float cnv_inv_height = 1.0f / cnv_height;
+ const float left = 2.0f * (get_left() * cnv_inv_width - 0.5f);
+ const float right = 2.0f * (get_right() * cnv_inv_width - 0.5f);
+ const float top = -2.0f * (get_top() * cnv_inv_height - 0.5f);
+ const float bottom = -2.0f * (get_bottom() * cnv_inv_height - 0.5f);
+#else
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const float inv_zoom = (float)camera.get_inv_zoom();
+
+ const float cnv_half_width = 0.5f * (float)cnv_size.get_width();
+ const float cnv_half_height = 0.5f * (float)cnv_size.get_height();
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
return;
- Vec2d start(m_start_corner(0) - cnv_half_width, cnv_half_height - m_start_corner(1));
- Vec2d end(m_end_corner(0) - cnv_half_width, cnv_half_height - m_end_corner(1));
+ const Vec2d start(m_start_corner.x() - cnv_half_width, cnv_half_height - m_start_corner.y());
+ const Vec2d end(m_end_corner.x() - cnv_half_width, cnv_half_height - m_end_corner.y());
+
+ const float left = (float)std::min(start.x(), end.x()) * inv_zoom;
+ const float top = (float)std::max(start.y(), end.y()) * inv_zoom;
+ const float right = (float)std::max(start.x(), end.x()) * inv_zoom;
+ const float bottom = (float)std::min(start.y(), end.y()) * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
- const float left = (float)std::min(start(0), end(0)) * inv_zoom;
- const float top = (float)std::max(start(1), end(1)) * inv_zoom;
- const float right = (float)std::max(start(0), end(0)) * inv_zoom;
- const float bottom = (float)std::min(start(1), end(1)) * inv_zoom;
-
glsafe(::glLineWidth(1.5f));
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
float color[3];
color[0] = (m_state == EState::Select) ? 0.3f : 1.0f;
color[1] = (m_state == EState::Select) ? 1.0f : 0.3f;
color[2] = 0.3f;
glsafe(::glColor3fv(color));
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// ensure that the rectangle is renderered inside the frustrum
@@ -109,13 +124,18 @@ namespace GUI {
// ensure that the overlay fits the frustrum near z plane
const double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushAttrib(GL_ENABLE_BIT));
glsafe(::glLineStipple(4, 0xAAAA));
glsafe(::glEnable(GL_LINE_STIPPLE));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
@@ -125,7 +145,7 @@ namespace GUI {
m_rectangle.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
init_data.reserve_vertices(4);
init_data.reserve_indices(4);
@@ -136,19 +156,20 @@ namespace GUI {
init_data.add_vertex(Vec2f(left, top));
// indices
- init_data.add_ushort_index(0);
- init_data.add_ushort_index(1);
- init_data.add_ushort_index(2);
- init_data.add_ushort_index(3);
+ init_data.add_index(0);
+ init_data.add_index(1);
+ init_data.add_index(2);
+ init_data.add_index(3);
m_rectangle.init_from(std::move(init_data));
}
- const ColorRGBA color(
- (m_state == EState::Select) ? 0.3f : 1.0f,
- (m_state == EState::Select) ? 1.0f : 0.3f,
- 0.3f, 1.0f);
- m_rectangle.set_color(color);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("view_model_matrix", Transform3d::Identity());
+ shader->set_uniform("projection_matrix", Transform3d::Identity());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
+ m_rectangle.set_color(ColorRGBA((m_state == EState::Select) ? 0.3f : 1.0f, (m_state == EState::Select) ? 1.0f : 0.3f, 0.3f, 1.0f));
m_rectangle.render();
shader->stop_using();
}
@@ -159,11 +180,13 @@ namespace GUI {
::glVertex2f((GLfloat)right, (GLfloat)top);
::glVertex2f((GLfloat)left, (GLfloat)top);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopAttrib());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
} // namespace GUI
diff --git a/src/slic3r/GUI/GLSelectionRectangle.hpp b/src/slic3r/GUI/GLSelectionRectangle.hpp
index e76420df0..f18dc4a6a 100644
--- a/src/slic3r/GUI/GLSelectionRectangle.hpp
+++ b/src/slic3r/GUI/GLSelectionRectangle.hpp
@@ -2,9 +2,9 @@
#define slic3r_GLSelectionRectangle_hpp_
#include "libslic3r/Point.hpp"
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "GLModel.hpp"
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
namespace Slic3r {
namespace GUI {
@@ -53,11 +53,11 @@ private:
EState m_state{ EState::Off };
Vec2d m_start_corner{ Vec2d::Zero() };
Vec2d m_end_corner{ Vec2d::Zero() };
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_rectangle;
Vec2d m_old_start_corner{ Vec2d::Zero() };
Vec2d m_old_end_corner{ Vec2d::Zero() };
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
diff --git a/src/slic3r/GUI/GLShader.cpp b/src/slic3r/GUI/GLShader.cpp
index 32b3d5960..7e5704e87 100644
--- a/src/slic3r/GUI/GLShader.cpp
+++ b/src/slic3r/GUI/GLShader.cpp
@@ -296,6 +296,13 @@ void GLShaderProgram::set_uniform(int id, const Matrix3f& value) const
glsafe(::glUniformMatrix3fv(id, 1, GL_FALSE, static_cast(value.data())));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const
+{
+ set_uniform(id, (Matrix3f)value.cast());
+}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
void GLShaderProgram::set_uniform(int id, const Vec3f& value) const
{
if (id >= 0)
diff --git a/src/slic3r/GUI/GLShader.hpp b/src/slic3r/GUI/GLShader.hpp
index 06a5c00e5..a867a62bd 100644
--- a/src/slic3r/GUI/GLShader.hpp
+++ b/src/slic3r/GUI/GLShader.hpp
@@ -61,6 +61,9 @@ public:
void set_uniform(const char* name, const Transform3f& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const Transform3d& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const Matrix3f& value) const { set_uniform(get_uniform_location(name), value); }
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); }
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); }
void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); }
@@ -80,6 +83,9 @@ public:
void set_uniform(int id, const Transform3f& value) const;
void set_uniform(int id, const Transform3d& value) const;
void set_uniform(int id, const Matrix3f& value) const;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void set_uniform(int id, const Matrix3d& value) const;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void set_uniform(int id, const Vec3f& value) const;
void set_uniform(int id, const Vec3d& value) const;
void set_uniform(int id, const ColorRGB& value) const;
diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp
index 33ac9b6bc..75b6824a7 100644
--- a/src/slic3r/GUI/GLShadersManager.cpp
+++ b/src/slic3r/GUI/GLShadersManager.cpp
@@ -33,47 +33,91 @@ std::pair GLShadersManager::init()
bool valid = true;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ // basic shader, used to render all what was previously rendered using the immediate mode
+ valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" });
+ // basic shader for textures, used to render textures
+ valid &= append_shader("flat_texture_attr", { "flat_texture_attr.vs", "flat_texture.fs" });
+ // used to render 3D scene background
+ valid &= append_shader("background_attr", { "background_attr.vs", "background.fs" });
+#else
// basic shader, used to render all what was previously rendered using the immediate mode
valid &= append_shader("flat", { "flat.vs", "flat.fs" });
// basic shader for textures, used to render textures
valid &= append_shader("flat_texture", { "flat_texture.vs", "flat_texture.fs" });
// used to render 3D scene background
valid &= append_shader("background", { "background.vs", "background.fs" });
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#if ENABLE_SHOW_TOOLPATHS_COG
// used to render toolpaths center of gravity
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ valid &= append_shader("toolpaths_cog_attr", { "toolpaths_cog_attr.vs", "toolpaths_cog.fs" });
+#else
valid &= append_shader("toolpaths_cog", { "toolpaths_cog.vs", "toolpaths_cog.fs" });
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#endif // ENABLE_SHOW_TOOLPATHS_COG
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ // 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_attr", { "gouraud_light_attr.vs", "gouraud_light.fs" });
+ // used to render printbed
+ valid &= append_shader("printbed_attr", { "printbed_attr.vs", "printbed.fs" });
+#else
// 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 printbed
valid &= append_shader("printbed", { "printbed.vs", "printbed.fs" });
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// used to render options in gcode preview
- if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3))
+ if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ valid &= append_shader("gouraud_light_instanced_attr", { "gouraud_light_instanced_attr.vs", "gouraud_light_instanced.fs" });
+#else
valid &= append_shader("gouraud_light_instanced", { "gouraud_light_instanced.vs", "gouraud_light_instanced.fs" });
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ }
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ // used to render objects in 3d editor
+ valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" }
+#else
// 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" }
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#if ENABLE_ENVIRONMENT_MAP
, { "ENABLE_ENVIRONMENT_MAP"sv }
#endif // ENABLE_ENVIRONMENT_MAP
);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ // used to render variable layers heights in 3d editor
+ valid &= append_shader("variable_layer_height_attr", { "variable_layer_height_attr.vs", "variable_layer_height.fs" });
+ // used to render highlight contour around selected triangles inside the multi-material gizmo
+ valid &= append_shader("mm_contour_attr", { "mm_contour_attr.vs", "mm_contour_attr.fs" });
+#else
// used to render variable layers heights in 3d editor
valid &= append_shader("variable_layer_height", { "variable_layer_height.vs", "variable_layer_height.fs" });
// used to render highlight contour around selected triangles inside the multi-material gizmo
valid &= append_shader("mm_contour", { "mm_contour.vs", "mm_contour.fs" });
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// Used to render painted triangles inside the multi-material gizmo. Triangle normals are computed inside fragment shader.
// 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.
// Since macOS 12 (Monterey), this issue with the opposite direction on Apple's Arm CPU seems to be fixed, and computed
// triangle normals inside fragment shader have the right direction.
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
+ valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" }, { "FLIP_TRIANGLE_NORMALS"sv });
+ else
+ valid &= append_shader("mm_gouraud_attr", { "mm_gouraud_attr.vs", "mm_gouraud_attr.fs" });
+#else
if (platform_flavor() == PlatformFlavor::OSXOnArm && wxPlatformInfo::Get().GetOSMajorVersion() < 12)
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"}, {"FLIP_TRIANGLE_NORMALS"sv});
else
valid &= append_shader("mm_gouraud", {"mm_gouraud.vs", "mm_gouraud.fs"});
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
return { valid, error };
}
diff --git a/src/slic3r/GUI/GLTexture.cpp b/src/slic3r/GUI/GLTexture.cpp
index 340bb78c3..064ca1a18 100644
--- a/src/slic3r/GUI/GLTexture.cpp
+++ b/src/slic3r/GUI/GLTexture.cpp
@@ -3,10 +3,10 @@
#include "3DScene.hpp"
#include "OpenGLManager.hpp"
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "GUI_App.hpp"
#include "GLModel.hpp"
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include
@@ -339,9 +339,9 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)tex_id));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 };
init_data.reserve_vertices(4);
init_data.reserve_indices(6);
@@ -352,15 +352,23 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
init_data.add_vertex(Vec2f(left, top), Vec2f(uvs.left_top.u, uvs.left_top.v));
// indices
- init_data.add_ushort_triangle(0, 1, 2);
- init_data.add_ushort_triangle(2, 3, 0);
+ init_data.add_triangle(0, 1, 2);
+ init_data.add_triangle(2, 3, 0);
GLModel model;
model.init_from(std::move(init_data));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_texture_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat_texture");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("view_model_matrix", Transform3d::Identity());
+ shader->set_uniform("projection_matrix", Transform3d::Identity());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
model.render();
shader->stop_using();
}
@@ -371,7 +379,7 @@ void GLTexture::render_sub_texture(unsigned int tex_id, float left, float right,
::glTexCoord2f(uvs.right_top.u, uvs.right_top.v); ::glVertex2f(right, top);
::glTexCoord2f(uvs.left_top.u, uvs.left_top.v); ::glVertex2f(left, top);
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glBindTexture(GL_TEXTURE_2D, 0));
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 86827442d..78fbc084f 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -85,26 +85,29 @@ bool GLToolbarItem::update_enabled_state()
return ret;
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLToolbarItem::render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
+#else
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
- auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) -> GLTexture::Quad_UVs
- {
- assert((tex_width != 0) && (tex_height != 0));
+ auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) -> GLTexture::Quad_UVs {
+ assert(tex_width != 0 && tex_height != 0);
GLTexture::Quad_UVs ret;
// tiles in the texture are spaced by 1 pixel
- float icon_size_px = (float)(tex_width - 1) / ((float)Num_States + (float)Num_Rendered_Highlight_States);
- char render_state = (m_highlight_state == NotHighlighted ? m_state : Num_States + m_highlight_state);
- float inv_tex_width = 1.0f / (float)tex_width;
- float inv_tex_height = 1.0f / (float)tex_height;
+ const float icon_size_px = (float)(tex_width - 1) / ((float)Num_States + (float)Num_Rendered_Highlight_States);
+ const char render_state = (m_highlight_state == NotHighlighted ? m_state : Num_States + m_highlight_state);
+ const float inv_tex_width = 1.0f / (float)tex_width;
+ const float inv_tex_height = 1.0f / (float)tex_height;
// tiles in the texture are spaced by 1 pixel
- float u_offset = 1.0f * inv_tex_width;
- float v_offset = 1.0f * inv_tex_height;
- float du = icon_size_px * inv_tex_width;
- float dv = icon_size_px * inv_tex_height;
- float left = u_offset + (float)render_state * du;
- float right = left + du - u_offset;
- float top = v_offset + (float)m_data.sprite_id * dv;
- float bottom = top + dv - v_offset;
+ const float u_offset = 1.0f * inv_tex_width;
+ const float v_offset = 1.0f * inv_tex_height;
+ const float du = icon_size_px * inv_tex_width;
+ const float dv = icon_size_px * inv_tex_height;
+ const float left = u_offset + (float)render_state * du;
+ const float right = left + du - u_offset;
+ const float top = v_offset + (float)m_data.sprite_id * dv;
+ const float bottom = top + dv - v_offset;
ret.left_top = { left, top };
ret.left_bottom = { left, bottom };
ret.right_bottom = { right, bottom };
@@ -114,12 +117,26 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, uvs(tex_width, tex_height, icon_size));
- if (is_pressed())
- {
- if ((m_last_action_type == Left) && m_data.left.can_render())
+ if (is_pressed()) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Size cnv_size = parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ const float out_left = (0.5f * left + 0.5f) * cnv_w;
+ const float out_right = (0.5f * right + 0.5f) * cnv_w;
+ const float out_top = (0.5f * top + 0.5f) * cnv_h;
+ const float out_bottom = (0.5f * bottom + 0.5f) * cnv_h;
+ if (m_last_action_type == Left && m_data.left.can_render())
+ m_data.left.render_callback(out_left, out_right, out_bottom, out_top);
+ else if (m_last_action_type == Right && m_data.right.can_render())
+ m_data.right.render_callback(out_left, out_right, out_bottom, out_top);
+#else
+ if (m_last_action_type == Left && m_data.left.can_render())
m_data.left.render_callback(left, right, bottom, top);
- else if ((m_last_action_type == Right) && m_data.right.can_render())
+ else if (m_last_action_type == Right && m_data.right.can_render())
m_data.right.render_callback(left, right, bottom, top);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
}
}
@@ -185,6 +202,16 @@ bool GLToolbar::init(const BackgroundTexture::Metadata& background_texture)
return res;
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+bool GLToolbar::init_arrow(const std::string& filename)
+{
+ if (m_arrow_texture.get_id() != 0)
+ return true;
+
+ const std::string path = resources_dir() + "/icons/";
+ return (!filename.empty()) ? m_arrow_texture.load_from_svg_file(path + filename, false, false, false, 512) : false;
+}
+#else
bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
{
if (m_arrow_texture.texture.get_id() != 0)
@@ -193,14 +220,15 @@ bool GLToolbar::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
std::string path = resources_dir() + "/icons/";
bool res = false;
- if (!arrow_texture.filename.empty()) {
+ if (!arrow_texture.filename.empty())
res = m_arrow_texture.texture.load_from_svg_file(path + arrow_texture.filename, false, false, false, 1000);
- }
+
if (res)
m_arrow_texture.metadata = arrow_texture;
return res;
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
GLToolbar::Layout::EType GLToolbar::get_layout_type() const
{
@@ -434,18 +462,16 @@ void GLToolbar::render(const GLCanvas3D& parent)
{
default:
case Layout::Horizontal: { render_horizontal(parent); break; }
- case Layout::Vertical: { render_vertical(parent); break; }
+ case Layout::Vertical: { render_vertical(parent); break; }
}
}
-
-
bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
{
if (!m_enabled)
return false;
- Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
+ const Vec2d mouse_pos((double)evt.GetX(), (double)evt.GetY());
bool processed = false;
// mouse anywhere
@@ -493,7 +519,7 @@ bool GLToolbar::on_mouse(wxMouseEvent& evt, GLCanvas3D& parent)
return false;
}
- int item_id = contains_mouse(mouse_pos, parent);
+ const int item_id = contains_mouse(mouse_pos, parent);
if (item_id != -1) {
// mouse inside toolbar
if (evt.LeftDown() || evt.LeftDClick()) {
@@ -601,16 +627,12 @@ int GLToolbar::get_visible_items_cnt() const
void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas3D& parent, bool check_hover)
{
- if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id))
- {
- if ((0 <= item_id) && (item_id < (int)m_items.size()))
- {
+ if (m_pressed_toggable_id == -1 || m_pressed_toggable_id == item_id) {
+ if (0 <= item_id && item_id < (int)m_items.size()) {
GLToolbarItem* item = m_items[item_id];
- if ((item != nullptr) && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered()))
- {
- if (((type == GLToolbarItem::Right) && item->is_right_toggable()) ||
- ((type == GLToolbarItem::Left) && item->is_left_toggable()))
- {
+ if (item != nullptr && !item->is_separator() && !item->is_disabled() && (!check_hover || item->is_hovered())) {
+ if ((type == GLToolbarItem::Right && item->is_right_toggable()) ||
+ (type == GLToolbarItem::Left && item->is_left_toggable())) {
GLToolbarItem::EState state = item->get_state();
if (state == GLToolbarItem::Hover)
item->set_state(GLToolbarItem::HoverPressed);
@@ -628,12 +650,11 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas
switch (type)
{
default:
- case GLToolbarItem::Left: { item->do_left_action(); break; }
+ case GLToolbarItem::Left: { item->do_left_action(); break; }
case GLToolbarItem::Right: { item->do_right_action(); break; }
}
}
- else
- {
+ else {
if (m_type == Radio)
select_item(item->get_name());
else
@@ -648,8 +669,7 @@ void GLToolbar::do_action(GLToolbarItem::EActionType type, int item_id, GLCanvas
case GLToolbarItem::Right: { item->do_right_action(); break; }
}
- if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled))
- {
+ if (m_type == Normal && item->get_state() != GLToolbarItem::Disabled) {
// the item may get disabled during the action, if not, set it back to hover state
item->set_state(GLToolbarItem::Hover);
parent.render();
@@ -669,10 +689,209 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
default:
case Layout::Horizontal: { update_hover_state_horizontal(mouse_pos, parent); break; }
- case Layout::Vertical: { update_hover_state_vertical(mouse_pos, parent); break; }
+ case Layout::Vertical: { update_hover_state_vertical(mouse_pos, parent); break; }
}
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
+
+ const float icons_size = m_layout.icons_size * m_layout.scale;
+ const float separator_size = m_layout.separator_size * m_layout.scale;
+ const float gap_size = m_layout.gap_size * m_layout.scale;
+ const float border = m_layout.border * m_layout.scale;
+
+ const float separator_stride = separator_size + gap_size;
+ const float icon_stride = icons_size + gap_size;
+
+ float left = m_layout.left + border;
+ float top = m_layout.top - border;
+
+ for (GLToolbarItem* item : m_items) {
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator())
+ left += separator_stride;
+ else {
+ const float right = left + icons_size;
+ const float bottom = top - icons_size;
+
+ const GLToolbarItem::EState state = item->get_state();
+ bool inside = (left <= (float)scaled_mouse_pos.x()) &&
+ ((float)scaled_mouse_pos.x() <= right) &&
+ (bottom <= (float)scaled_mouse_pos.y()) &&
+ ((float)scaled_mouse_pos.y() <= top);
+
+ switch (state)
+ {
+ case GLToolbarItem::Normal:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::Hover);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Hover:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Normal);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Pressed:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::HoverPressed);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::HoverPressed:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Pressed);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Disabled:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::HoverDisabled);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::HoverDisabled:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Disabled);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ left += icon_stride;
+ }
+ }
+}
+
+void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent)
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
+
+ const float icons_size = m_layout.icons_size * m_layout.scale;
+ const float separator_size = m_layout.separator_size * m_layout.scale;
+ const float gap_size = m_layout.gap_size * m_layout.scale;
+ const float border = m_layout.border * m_layout.scale;
+
+ const float separator_stride = separator_size + gap_size;
+ const float icon_stride = icons_size + gap_size;
+
+ float left = m_layout.left + border;
+ float top = m_layout.top - border;
+
+ for (GLToolbarItem* item : m_items) {
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator())
+ top -= separator_stride;
+ else {
+ const float right = left + icons_size;
+ const float bottom = top - icons_size;
+
+ GLToolbarItem::EState state = item->get_state();
+ const bool inside = (left <= (float)scaled_mouse_pos.x()) &&
+ ((float)scaled_mouse_pos.x() <= right) &&
+ (bottom <= (float)scaled_mouse_pos.y()) &&
+ ((float)scaled_mouse_pos.y() <= top);
+
+ switch (state)
+ {
+ case GLToolbarItem::Normal:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::Hover);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Hover:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Normal);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Pressed:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::HoverPressed);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::HoverPressed:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Pressed);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::Disabled:
+ {
+ if (inside) {
+ item->set_state(GLToolbarItem::HoverDisabled);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ case GLToolbarItem::HoverDisabled:
+ {
+ if (!inside) {
+ item->set_state(GLToolbarItem::Disabled);
+ parent.set_as_dirty();
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ top -= icon_stride;
+ }
+ }
+}
+#else
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent)
{
// NB: mouse_pos is already scaled appropriately
@@ -889,18 +1108,16 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D&
}
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
GLToolbarItem* GLToolbar::get_item(const std::string& item_name)
{
if (!m_enabled)
return nullptr;
- for (GLToolbarItem* item : m_items)
- {
- if (item->get_name() == item_name)
- {
+ for (GLToolbarItem* item : m_items) {
+ if (item->get_name() == item_name)
return item;
- }
}
return nullptr;
}
@@ -914,10 +1131,159 @@ int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent)
{
default:
case Layout::Horizontal: { return contains_mouse_horizontal(mouse_pos, parent); }
- case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); }
+ case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); }
}
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
+
+ const float icons_size = m_layout.icons_size * m_layout.scale;
+ const float separator_size = m_layout.separator_size * m_layout.scale;
+ const float gap_size = m_layout.gap_size * m_layout.scale;
+ const float border = m_layout.border * m_layout.scale;
+
+ float left = m_layout.left + border;
+ const float top = m_layout.top - border;
+
+ for (size_t id = 0; id < m_items.size(); ++id) {
+ GLToolbarItem* item = m_items[id];
+
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator()) {
+ float right = left + separator_size;
+ const float bottom = top - icons_size;
+
+ // mouse inside the separator
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return id;
+
+ left = right;
+ right += gap_size;
+
+ if (id < m_items.size() - 1) {
+ // mouse inside the gap
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return -2;
+ }
+
+ left = right;
+ }
+ else {
+ float right = left + icons_size;
+ const float bottom = top - icons_size;
+
+ // mouse inside the icon
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return id;
+
+ left = right;
+ right += gap_size;
+
+ if (id < m_items.size() - 1) {
+ // mouse inside the gap
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return -2;
+ }
+
+ left = right;
+ }
+ }
+
+ return -1;
+}
+
+int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const Vec2d scaled_mouse_pos((mouse_pos.x() - 0.5 * (double)cnv_size.get_width()), (0.5 * (double)cnv_size.get_height() - mouse_pos.y()));
+
+ const float icons_size = m_layout.icons_size * m_layout.scale;
+ const float separator_size = m_layout.separator_size * m_layout.scale;
+ const float gap_size = m_layout.gap_size * m_layout.scale;
+ const float border = m_layout.border * m_layout.scale;
+
+ const float left = m_layout.left + border;
+ float top = m_layout.top - border;
+
+ for (size_t id = 0; id < m_items.size(); ++id) {
+ GLToolbarItem* item = m_items[id];
+
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator()) {
+ const float right = left + icons_size;
+ float bottom = top - separator_size;
+
+ // mouse inside the separator
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return id;
+
+ top = bottom;
+ bottom -= gap_size;
+
+ if (id < m_items.size() - 1) {
+ // mouse inside the gap
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return -2;
+ }
+
+ top = bottom;
+ }
+ else {
+ const float right = left + icons_size;
+ float bottom = top - icons_size;
+
+ // mouse inside the icon
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return id;
+
+ top = bottom;
+ bottom -= gap_size;
+
+ if (id < m_items.size() - 1) {
+ // mouse inside the gap
+ if (left <= (float)scaled_mouse_pos.x() &&
+ (float)scaled_mouse_pos.x() <= right &&
+ bottom <= (float)scaled_mouse_pos.y() &&
+ (float)scaled_mouse_pos.y() <= top)
+ return -2;
+ }
+
+ top = bottom;
+ }
+ }
+
+ return -1;
+}
+#else
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
{
// NB: mouse_pos is already scaled appropriately
@@ -1062,14 +1428,92 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D&
return -1;
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLToolbar::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const
+{
+ const unsigned int tex_id = m_background_texture.texture.get_id();
+ const float tex_width = (float)m_background_texture.texture.get_width();
+ const float tex_height = (float)m_background_texture.texture.get_height();
+ if (tex_id != 0 && tex_width > 0.0f && tex_height > 0.0f) {
+ const float inv_tex_width = 1.0f / tex_width;
+ const float inv_tex_height = 1.0f / tex_height;
+
+ const float internal_left = left + border_w;
+ const float internal_right = right - border_w;
+ const float internal_top = top - border_h;
+ const float internal_bottom = bottom + border_w;
+
+ const float left_uv = 0.0f;
+ const float right_uv = 1.0f;
+ const float top_uv = 1.0f;
+ const float bottom_uv = 0.0f;
+
+ const float internal_left_uv = (float)m_background_texture.metadata.left * inv_tex_width;
+ const float internal_right_uv = 1.0f - (float)m_background_texture.metadata.right * inv_tex_width;
+ const float internal_top_uv = 1.0f - (float)m_background_texture.metadata.top * inv_tex_height;
+ const float internal_bottom_uv = (float)m_background_texture.metadata.bottom * inv_tex_height;
+
+ // top-left corner
+ if (m_layout.horizontal_orientation == Layout::HO_Left || m_layout.vertical_orientation == Layout::VO_Top)
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { left_uv, internal_top_uv }, { internal_left_uv, internal_top_uv }, { internal_left_uv, top_uv }, { left_uv, top_uv } });
+
+ // top edge
+ if (m_layout.vertical_orientation == Layout::VO_Top)
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } });
+
+ // top-right corner
+ if (m_layout.horizontal_orientation == Layout::HO_Right || m_layout.vertical_orientation == Layout::VO_Top)
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } });
+
+ // center-left edge
+ if (m_layout.horizontal_orientation == Layout::HO_Left)
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { left_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv }, { internal_left_uv, internal_top_uv }, { left_uv, internal_top_uv } });
+
+ // center
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+
+ // center-right edge
+ if (m_layout.horizontal_orientation == Layout::HO_Right)
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } });
+
+ // bottom-left corner
+ if (m_layout.horizontal_orientation == Layout::HO_Left || m_layout.vertical_orientation == Layout::VO_Bottom)
+ GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { left_uv, bottom_uv }, { internal_left_uv, bottom_uv }, { internal_left_uv, internal_bottom_uv }, { left_uv, internal_bottom_uv } });
+
+ // bottom edge
+ if (m_layout.vertical_orientation == Layout::VO_Bottom)
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } });
+
+ // bottom-right corner
+ if (m_layout.horizontal_orientation == Layout::HO_Right || m_layout.vertical_orientation == Layout::VO_Bottom)
+ GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+ else
+ GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
+ }
+}
+#else
void GLToolbar::render_background(float left, float top, float right, float bottom, float border) const
{
unsigned int tex_id = m_background_texture.texture.get_id();
float tex_width = (float)m_background_texture.texture.get_width();
float tex_height = (float)m_background_texture.texture.get_height();
- if ((tex_id != 0) && (tex_width > 0) && (tex_height > 0))
- {
+ if (tex_id != 0 && tex_width > 0 && tex_height > 0) {
float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f;
float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f;
@@ -1140,7 +1584,78 @@ void GLToolbar::render_background(float left, float top, float right, float bott
GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item)
+{
+ // arrow texture not initialized
+ if (m_arrow_texture.get_id() == 0)
+ return;
+
+ const Size cnv_size = parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ if (cnv_w == 0 || cnv_h == 0)
+ return;
+
+ const float inv_cnv_w = 1.0f / cnv_w;
+ const float inv_cnv_h = 1.0f / cnv_h;
+
+ const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w;
+ const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h;
+ const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w;
+ const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w;
+ const float border_x = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w;
+ const float border_y = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h;
+
+ const float separator_stride = separator_size + gap_size;
+ const float icon_stride = icons_size_x + gap_size;
+
+ float left = 2.0f * m_layout.left * inv_cnv_w + border_x;
+ float top = 2.0f * m_layout.top * inv_cnv_h - 2.0f * border_y - icons_size_y;
+
+ bool found = false;
+ for (const GLToolbarItem* item : m_items) {
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator())
+ left += separator_stride;
+ else {
+ if (item->get_name() == highlighted_item->get_name()) {
+ found = true;
+ break;
+ }
+ left += icon_stride;
+ }
+ }
+ if (!found)
+ return;
+
+ const float right = left + icons_size_x;
+
+ const unsigned int tex_id = m_arrow_texture.get_id();
+ // arrow width and height
+ const float arr_tex_width = (float)m_arrow_texture.get_width();
+ const float arr_tex_height = (float)m_arrow_texture.get_height();
+ if (tex_id != 0 && arr_tex_width > 0.0f && arr_tex_height > 0.0f) {
+ const float arrow_size_x = 2.0f * m_layout.scale * arr_tex_width * inv_cnv_w;
+ const float arrow_size_y = 2.0f * m_layout.scale * arr_tex_height * inv_cnv_h;
+
+ const float left_uv = 0.0f;
+ const float right_uv = 1.0f;
+ const float top_uv = 1.0f;
+ const float bottom_uv = 0.0f;
+
+ top -= border_y;
+ const float bottom = top - arrow_size_y * icons_size_x / arrow_size_x;
+
+ GLTexture::render_sub_texture(tex_id, left, right, bottom, top, { { left_uv, top_uv }, { right_uv, top_uv }, { right_uv, bottom_uv }, { left_uv, bottom_uv } });
+ }
+}
+#else
void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighted_item)
{
// arrow texture not initialized
@@ -1206,7 +1721,119 @@ void GLToolbar::render_arrow(const GLCanvas3D& parent, GLToolbarItem* highlighte
GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } });
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLToolbar::render_horizontal(const GLCanvas3D& parent)
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ if (cnv_w == 0 || cnv_h == 0)
+ return;
+
+ const unsigned int tex_id = m_icons_texture.get_id();
+ const int tex_width = m_icons_texture.get_width();
+ const int tex_height = m_icons_texture.get_height();
+
+ if (tex_id == 0 || tex_width <= 0 || tex_height <= 0)
+ return;
+
+ const float inv_cnv_w = 1.0f / cnv_w;
+ const float inv_cnv_h = 1.0f / cnv_h;
+
+ const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w;
+ const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h;
+ const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_w;
+ const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_w;
+ const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w;
+ const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h;
+ const float width = 2.0f * get_width() * inv_cnv_w;
+ const float height = 2.0f * get_height() * inv_cnv_h;
+
+ const float separator_stride = separator_size + gap_size;
+ const float icon_stride = icons_size_x + gap_size;
+
+ float left = 2.0f * m_layout.left * inv_cnv_w;
+ float top = 2.0f * m_layout.top * inv_cnv_h;
+ const float right = left + width;
+ const float bottom = top - height;
+
+ render_background(left, top, right, bottom, border_w, border_h);
+
+ left += border_w;
+ top -= border_h;
+
+ // renders icons
+ for (const GLToolbarItem* item : m_items) {
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator())
+ left += separator_stride;
+ else {
+ item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
+ left += icon_stride;
+ }
+ }
+}
+
+void GLToolbar::render_vertical(const GLCanvas3D& parent)
+{
+ const Size cnv_size = parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ if (cnv_w == 0 || cnv_h == 0)
+ return;
+
+ const unsigned int tex_id = m_icons_texture.get_id();
+ const int tex_width = m_icons_texture.get_width();
+ const int tex_height = m_icons_texture.get_height();
+
+ if (tex_id == 0 || tex_width <= 0 || tex_height <= 0)
+ return;
+
+ const float inv_cnv_w = 1.0f / cnv_w;
+ const float inv_cnv_h = 1.0f / cnv_h;
+
+ const float icons_size_x = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_w;
+ const float icons_size_y = 2.0f * m_layout.icons_size * m_layout.scale * inv_cnv_h;
+ const float separator_size = 2.0f * m_layout.separator_size * m_layout.scale * inv_cnv_h;
+ const float gap_size = 2.0f * m_layout.gap_size * m_layout.scale * inv_cnv_h;
+ const float border_w = 2.0f * m_layout.border * m_layout.scale * inv_cnv_w;
+ const float border_h = 2.0f * m_layout.border * m_layout.scale * inv_cnv_h;
+ const float width = 2.0f * get_width() * inv_cnv_w;
+ const float height = 2.0f * get_height() * inv_cnv_h;
+
+ const float separator_stride = separator_size + gap_size;
+ const float icon_stride = icons_size_y + gap_size;
+
+ float left = 2.0f * m_layout.left * inv_cnv_w;
+ float top = 2.0f * m_layout.top * inv_cnv_h;
+ const float right = left + width;
+ const float bottom = top - height;
+
+ render_background(left, top, right, bottom, border_w, border_h);
+
+ left += border_w;
+ top -= border_h;
+
+ // renders icons
+ for (const GLToolbarItem* item : m_items) {
+ if (!item->is_visible())
+ continue;
+
+ if (item->is_separator())
+ top -= separator_stride;
+ else {
+ item->render(parent, tex_id, left, left + icons_size_x, top - icons_size_y, top, (unsigned int)tex_width, (unsigned int)tex_height, (unsigned int)(m_layout.icons_size * m_layout.scale));
+ top -= icon_stride;
+ }
+ }
+}
+#else
void GLToolbar::render_horizontal(const GLCanvas3D& parent)
{
unsigned int tex_id = m_icons_texture.get_id();
@@ -1300,6 +1927,7 @@ void GLToolbar::render_vertical(const GLCanvas3D& parent)
}
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
bool GLToolbar::generate_icons_texture()
{
diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp
index 5740db3e6..bd3204d63 100644
--- a/src/slic3r/GUI/GLToolbar.hpp
+++ b/src/slic3r/GUI/GLToolbar.hpp
@@ -153,7 +153,12 @@ public:
// returns true if the state changes
bool update_enabled_state();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render(const GLCanvas3D& parent, unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
+#else
void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
private:
void set_visible(bool visible) { m_data.visible = visible; }
@@ -246,7 +251,11 @@ private:
GLTexture m_icons_texture;
bool m_icons_texture_dirty;
BackgroundTexture m_background_texture;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLTexture m_arrow_texture;
+#else
BackgroundTexture m_arrow_texture;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
Layout m_layout;
ItemsList m_items;
@@ -273,7 +282,11 @@ public:
bool init(const BackgroundTexture::Metadata& background_texture);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ bool init_arrow(const std::string& filename);
+#else
bool init_arrow(const BackgroundTexture::Metadata& arrow_texture);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
Layout::EType get_layout_type() const;
void set_layout_type(Layout::EType type);
@@ -344,7 +357,11 @@ private:
int contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const;
int contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
+#else
void render_background(float left, float top, float right, float bottom, float border) const;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void render_horizontal(const GLCanvas3D& parent);
void render_vertical(const GLCanvas3D& parent);
diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp
index 3ffd9ed84..87913fb81 100644
--- a/src/slic3r/GUI/GUI_App.cpp
+++ b/src/slic3r/GUI/GUI_App.cpp
@@ -873,6 +873,8 @@ void GUI_App::init_app_config()
// SetAppName(SLIC3R_APP_KEY);
SetAppName(SLIC3R_APP_KEY "-alpha");
// SetAppName(SLIC3R_APP_KEY "-beta");
+
+
// SetAppDisplayName(SLIC3R_APP_NAME);
// Set the Slic3r data directory at the Slic3r XS module.
diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
index 98012fa2d..6ab87150b 100644
--- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp
+++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp
@@ -657,9 +657,9 @@ void ObjectManipulation::update_if_dirty()
else
m_og->disable();
- if (!selection.is_dragging()) {
+ if (!wxGetApp().plater()->canvas3D()->is_dragging()) {
update_reset_buttons_visibility();
- update_mirror_buttons_visibility();
+ update_mirror_buttons_visibility();
}
m_dirty = false;
@@ -814,9 +814,8 @@ void ObjectManipulation::change_position_value(int axis, double value)
auto canvas = wxGetApp().plater()->canvas3D();
Selection& selection = canvas->get_selection();
- selection.start_dragging();
+ selection.setup_cache();
selection.translate(position - m_cache.position, selection.requires_local_axes());
- selection.stop_dragging();
canvas->do_move(L("Set Position"));
m_cache.position = position;
@@ -844,11 +843,10 @@ void ObjectManipulation::change_rotation_value(int axis, double value)
transformation_type.set_local();
}
- selection.start_dragging();
+ selection.setup_cache();
selection.rotate(
(M_PI / 180.0) * (transformation_type.absolute() ? rotation : rotation - m_cache.rotation),
transformation_type);
- selection.stop_dragging();
canvas->do_rotate(L("Set Orientation"));
m_cache.rotation = rotation;
@@ -925,9 +923,8 @@ void ObjectManipulation::do_scale(int axis, const Vec3d &scale) const
if (m_uniform_scale || selection.requires_uniform_scale())
scaling_factor = scale(axis) * Vec3d::Ones();
- selection.start_dragging();
+ selection.setup_cache();
selection.scale(scaling_factor, transformation_type);
- selection.stop_dragging();
wxGetApp().plater()->canvas3D()->do_scale(L("Set Scale"));
}
diff --git a/src/slic3r/GUI/GalleryDialog.cpp b/src/slic3r/GUI/GalleryDialog.cpp
index 0bc741c96..975b807dc 100644
--- a/src/slic3r/GUI/GalleryDialog.cpp
+++ b/src/slic3r/GUI/GalleryDialog.cpp
@@ -275,12 +275,12 @@ static void generate_thumbnail_from_model(const std::string& filename)
GLVolumeCollection volumes;
volumes.volumes.push_back(new GLVolume());
GLVolume* volume = volumes.volumes.back();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
volume->model.init_from(model.mesh());
#else
volume->indexed_vertex_array.load_mesh(model.mesh());
volume->indexed_vertex_array.finalize_geometry(true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
volume->set_instance_transformation(model.objects[0]->instances[0]->get_transformation());
volume->set_volume_transformation(model.objects[0]->volumes[0]->get_transformation());
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
index c24a2372d..83aed4289 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.cpp
@@ -4,8 +4,10 @@
#include
#include "slic3r/GUI/GUI_App.hpp"
-
#include "slic3r/GUI/GUI_ObjectManipulation.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "slic3r/GUI/Plater.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// TODO: Display tooltips quicker on Linux
@@ -33,34 +35,52 @@ float GLGizmoBase::Grabber::get_dragging_half_size(float size) const
void GLGizmoBase::Grabber::render(float size, const ColorRGBA& render_color, bool picking)
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_current_shader();
+ if (shader == nullptr)
+ return;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
if (!m_cube.is_initialized()) {
// This cannot be done in constructor, OpenGL is not yet
// initialized at that point (on Linux at least).
indexed_triangle_set its = its_make_cube(1., 1., 1.);
- its_translate(its, Vec3f(-0.5, -0.5, -0.5));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+ its_translate(its, -0.5f * Vec3f::Ones());
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cube.init_from(its);
#else
m_cube.init_from(its, BoundingBoxf3{ { -0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 } });
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
const float fullsize = 2.0f * (dragging ? get_dragging_half_size(size) : get_half_size(size));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cube.set_color(render_color);
#else
m_cube.set_color(-1, render_color);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() * matrix * Geometry::assemble_transform(center, angles, fullsize * Vec3d::Ones());
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", projection_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(center.x(), center.y(), center.z()));
glsafe(::glRotated(Geometry::rad2deg(angles.z()), 0.0, 0.0, 1.0));
glsafe(::glRotated(Geometry::rad2deg(angles.y()), 0.0, 1.0, 0.0));
glsafe(::glRotated(Geometry::rad2deg(angles.x()), 1.0, 0.0, 0.0));
glsafe(::glScaled(fullsize, fullsize, fullsize));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cube.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
@@ -114,7 +134,11 @@ void GLGizmoBase::render_grabbers(const BoundingBoxf3& box) const
void GLGizmoBase::render_grabbers(float size) const
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
shader->start_using();
@@ -128,11 +152,15 @@ void GLGizmoBase::render_grabbers(float size) const
void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
for (unsigned int i = 0; i < (unsigned int)m_grabbers.size(); ++i) {
@@ -141,10 +169,10 @@ void GLGizmoBase::render_grabbers_for_picking(const BoundingBoxf3& box) const
m_grabbers[i].render_for_picking(mean_size);
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
// help function to process grabbers
@@ -162,8 +190,7 @@ bool GLGizmoBase::use_grabbers(const wxMouseEvent &mouse_event) {
Selection &selection = m_parent.get_selection();
if (!selection.is_empty() && m_hover_id != -1 &&
(m_grabbers.empty() || m_hover_id < static_cast(m_grabbers.size()))) {
- // TODO: investigate if it is neccessary -> there was no stop dragging
- selection.start_dragging();
+ selection.setup_cache();
m_dragging = true;
for (auto &grabber : m_grabbers) grabber.dragging = false;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
index 6f62382e1..145320462 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoBase.hpp
@@ -49,6 +49,9 @@ protected:
bool dragging{ false };
Vec3d center{ Vec3d::Zero() };
Vec3d angles{ Vec3d::Zero() };
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ Transform3d matrix{ Transform3d::Identity() };
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
ColorRGBA color{ ColorRGBA::WHITE() };
Grabber() = default;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
index 095f1e7a5..5c9b08a93 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp
@@ -106,23 +106,27 @@ void GLGizmoCut::on_render()
glsafe(::glEnable(GL_BLEND));
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
- Vec3d diff = plane_center - m_old_center;
+ const Vec3d diff = plane_center - m_old_center;
// Z changed when move with cut plane
// X and Y changed when move with cutted object
bool is_changed = std::abs(diff.x()) > EPSILON ||
- std::abs(diff.y()) > EPSILON ||
- std::abs(diff.z()) > EPSILON;
+ std::abs(diff.y()) > EPSILON ||
+ std::abs(diff.z()) > EPSILON;
m_old_center = plane_center;
if (!m_plane.is_initialized() || is_changed) {
m_plane.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3 };
init_data.color = { 0.8f, 0.8f, 0.8f, 0.5f };
init_data.reserve_vertices(4);
init_data.reserve_indices(6);
@@ -134,12 +138,18 @@ void GLGizmoCut::on_render()
init_data.add_vertex(Vec3f(min_x, max_y, plane_center.z()));
// indices
- init_data.add_ushort_triangle(0, 1, 2);
- init_data.add_ushort_triangle(2, 3, 0);
+ init_data.add_triangle(0, 1, 2);
+ init_data.add_triangle(2, 3, 0);
m_plane.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
m_plane.render();
#else
// Draw the cutting plane
@@ -150,7 +160,7 @@ void GLGizmoCut::on_render()
::glVertex3f(max_x, max_y, plane_center.z());
::glVertex3f(min_x, max_y, plane_center.z());
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glEnable(GL_CULL_FACE));
glsafe(::glDisable(GL_BLEND));
@@ -162,12 +172,12 @@ void GLGizmoCut::on_render()
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
glsafe(::glLineWidth(m_hover_id != -1 ? 2.0f : 1.5f));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_grabber_connection.is_initialized() || is_changed) {
m_grabber_connection.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.color = ColorRGBA::YELLOW();
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
@@ -177,7 +187,7 @@ void GLGizmoCut::on_render()
init_data.add_vertex((Vec3f)m_grabbers[0].center.cast());
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_grabber_connection.init_from(std::move(init_data));
}
@@ -187,7 +197,11 @@ void GLGizmoCut::on_render()
shader->stop_using();
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
glsafe(::glColor3f(1.0, 1.0, 0.0));
::glBegin(GL_LINES);
@@ -196,7 +210,7 @@ void GLGizmoCut::on_render()
glsafe(::glEnd());
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -207,20 +221,32 @@ void GLGizmoCut::on_render()
shader->stop_using();
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("flat_attr");
+#else
shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix()* Geometry::assemble_transform(m_cut_contours.shift));
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_cut_contours.shift.x(), m_cut_contours.shift.y(), m_cut_contours.shift.z()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glLineWidth(2.0f));
m_cut_contours.contours.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLGizmoCut::on_render_for_picking()
@@ -383,11 +409,11 @@ void GLGizmoCut::update_contours()
const Polygons polys = slice_mesh(m_cut_contours.mesh.its, m_cut_z, slicing_params);
if (!polys.empty()) {
m_cut_contours.contours.init_from(polys, static_cast(m_cut_z));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cut_contours.contours.set_color(ColorRGBA::WHITE());
#else
m_cut_contours.contours.set_color(-1, { 1.0f, 1.0f, 1.0f, 1.0f });
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
}
else if (box.center() != m_cut_contours.position) {
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp
index feb23bf45..d81b53e5f 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.hpp
@@ -23,11 +23,11 @@ class GLGizmoCut : public GLGizmoBase
bool m_keep_upper{ true };
bool m_keep_lower{ true };
bool m_rotate_lower{ false };
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_plane;
GLModel m_grabber_connection;
Vec3d m_old_center;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
struct CutContours
{
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
index e0a583f0b..48c81bc5a 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp
@@ -1,9 +1,13 @@
// Include GLGizmoBase.hpp before I18N.hpp as it includes some libigl code, which overrides our localization "L" macro.
#include "GLGizmoFlatten.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GUI_App.hpp"
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "slic3r/GUI/Plater.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
#include "slic3r/GUI/Gizmos/GLGizmosCommon.hpp"
#include "libslic3r/Geometry/ConvexHull.hpp"
@@ -100,13 +104,17 @@ void GLGizmoFlatten::on_render()
{
const Selection& selection = m_parent.get_selection();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
shader->start_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
@@ -115,70 +123,96 @@ void GLGizmoFlatten::on_render()
if (selection.is_single_full_instance()) {
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() *
+ Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z() * Vec3d::UnitZ()) * m;
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
glsafe(::glMultMatrixd(m.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (this->is_plane_update_necessary())
update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_planes[i].vbo.set_color(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR : DEFAULT_PLANE_COLOR);
m_planes[i].vbo.render();
#else
glsafe(::glColor4fv(i == m_hover_id ? DEFAULT_HOVER_PLANE_COLOR.data() : DEFAULT_PLANE_COLOR.data()));
if (m_planes[i].vbo.has_VBOs())
m_planes[i].vbo.render();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
glsafe(::glEnable(GL_CULL_FACE));
glsafe(::glDisable(GL_BLEND));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLGizmoFlatten::on_render_for_picking()
{
const Selection& selection = m_parent.get_selection();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
shader->start_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
glsafe(::glDisable(GL_BLEND));
if (selection.is_single_full_instance() && !wxGetKeyState(WXK_CONTROL)) {
const Transform3d& m = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() *
+ Geometry::assemble_transform(selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z() * Vec3d::UnitZ()) * m;
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(0.f, 0.f, selection.get_volume(*selection.get_volume_idxs().begin())->get_sla_shift_z()));
glsafe(::glMultMatrixd(m.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (this->is_plane_update_necessary())
update_planes();
for (int i = 0; i < (int)m_planes.size(); ++i) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_planes[i].vbo.set_color(picking_color_component(i));
#else
glsafe(::glColor4fv(picking_color_component(i).data()));
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_planes[i].vbo.render();
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
glsafe(::glEnable(GL_CULL_FACE));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLGizmoFlatten::set_flattening_data(const ModelObject* model_object)
@@ -393,18 +427,15 @@ void GLGizmoFlatten::update_planes()
// And finally create respective VBOs. The polygon is convex with
// the vertices in order, so triangulation is trivial.
for (auto& plane : m_planes) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(plane.vertices.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::TriangleFan, GLModel::Geometry::EVertexLayout::P3N3 };
init_data.reserve_vertices(plane.vertices.size());
init_data.reserve_indices(plane.vertices.size());
// vertices + indices
for (size_t i = 0; i < plane.vertices.size(); ++i) {
init_data.add_vertex((Vec3f)plane.vertices[i].cast(), (Vec3f)plane.normal.cast());
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_index((unsigned short)i);
- else
- init_data.add_uint_index((unsigned int)i);
+ init_data.add_index((unsigned int)i);
}
plane.vbo.init_from(std::move(init_data));
#else
@@ -414,7 +445,7 @@ void GLGizmoFlatten::update_planes()
for (size_t i=1; i vertices; // should be in fact local in update_planes()
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel vbo;
#else
GLIndexedVertexArray vbo;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
Vec3d normal;
float area;
};
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
index ee97972af..ebf8aa21b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoHollow.cpp
@@ -103,11 +103,15 @@ void GLGizmoHollow::on_render_for_picking()
void GLGizmoHollow::render_points(const Selection& selection, bool picking)
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat") : wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
-
+
shader->start_using();
ScopeGuard guard([shader]() { shader->stop_using(); });
#else
@@ -115,23 +119,34 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
if (shader)
shader->start_using();
ScopeGuard guard([shader]() { if (shader) shader->stop_using(); });
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
+ const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix();
+
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d& view_matrix = camera.get_view_matrix();
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
+
+ shader->set_uniform("projection_matrix", projection_matrix);
+#else
const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, m_c->selection_info()->get_sla_shift()));
glsafe(::glMultMatrixd(instance_matrix.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
ColorRGBA render_color;
const sla::DrainHoles& drain_holes = m_c->selection_info()->model_object()->sla_drain_holes;
- size_t cache_size = drain_holes.size();
+ const size_t cache_size = drain_holes.size();
for (size_t i = 0; i < cache_size; ++i) {
const sla::DrainHole& drain_hole = drain_holes[i];
- const bool& point_selected = m_selected[i];
+ const bool point_selected = m_selected[i];
if (is_mesh_point_clipped(drain_hole.pos.cast()))
continue;
@@ -151,16 +166,20 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
render_color = point_selected ? ColorRGBA(1.0f, 0.3f, 0.3f, 0.5f) : ColorRGBA(1.0f, 1.0f, 1.0f, 0.5f);
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cylinder.set_color(render_color);
#else
const_cast(&m_cylinder)->set_color(-1, render_color);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse;
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (vol->is_left_handed())
glFrontFace(GL_CW);
@@ -168,20 +187,31 @@ void GLGizmoHollow::render_points(const Selection& selection, bool picking)
// Matrices set, we can render the point mark now.
Eigen::Quaterniond q;
q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast());
- Eigen::AngleAxisd aa(q);
+ const Eigen::AngleAxisd aa(q);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) *
+ Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
- glsafe(::glPushMatrix());
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cylinder.render();
- glsafe(::glPopMatrix());
if (vol->is_left_handed())
glFrontFace(GL_CCW);
- glsafe(::glPopMatrix());
+
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
- glsafe(::glPopMatrix());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
+ glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
bool GLGizmoHollow::is_mesh_point_clipped(const Vec3d& point) const
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp
index 24e90fceb..13c8a71c6 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp
@@ -170,7 +170,11 @@ void GLGizmoMmuSegmentation::data_changed()
void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
{
ClippingPlaneDataWrapper clp_data = this->get_clipping_plane_data();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto* shader = wxGetApp().get_shader("mm_gouraud_attr");
+#else
auto *shader = wxGetApp().get_shader("mm_gouraud");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (!shader)
return;
shader->start_using();
@@ -188,18 +192,32 @@ void GLGizmoMmuSegmentation::render_triangles(const Selection &selection) const
const Transform3d trafo_matrix = mo->instances[selection.get_instance_idx()]->get_transformation().get_matrix() * mv->get_matrix();
- bool is_left_handed = trafo_matrix.matrix().determinant() < 0.;
+ const bool is_left_handed = trafo_matrix.matrix().determinant() < 0.0;
if (is_left_handed)
glsafe(::glFrontFace(GL_CW));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
shader->set_uniform("volume_world_matrix", trafo_matrix);
shader->set_uniform("volume_mirrored", is_left_handed);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
+#else
m_triangle_selectors[mesh_id]->render(m_imgui);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
if (is_left_handed)
glsafe(::glFrontFace(GL_CCW));
}
@@ -568,7 +586,11 @@ ColorRGBA GLGizmoMmuSegmentation::get_cursor_sphere_right_button_color() const
return color;
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void TriangleSelectorMmGui::render(ImGuiWrapper* imgui, const Transform3d& matrix)
+#else
void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
if (m_update_render_data)
update_render_data();
@@ -576,7 +598,11 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
auto *shader = wxGetApp().get_current_shader();
if (!shader)
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ assert(shader->get_name() == "mm_gouraud_attr");
+#else
assert(shader->get_name() == "mm_gouraud");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx)
if (m_gizmo_scene.has_VBOs(color_idx)) {
@@ -588,8 +614,12 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
m_gizmo_scene.render(color_idx);
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_paint_contour(matrix);
+#else
render_paint_contour();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
if (m_paint_contour.has_VBO()) {
ScopeGuard guard_mm_gouraud([shader]() { shader->start_using(); });
@@ -604,7 +634,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
contour_shader->stop_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_update_render_data = false;
}
@@ -639,7 +669,7 @@ void TriangleSelectorMmGui::update_render_data()
m_gizmo_scene.finalize_triangle_indices();
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
update_paint_contour();
#else
m_paint_contour.release_geometry();
@@ -660,7 +690,7 @@ void TriangleSelectorMmGui::update_render_data()
m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size();
m_paint_contour.finalize_geometry();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp
index 6f357bb6f..5d2397337 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp
@@ -66,9 +66,13 @@ public:
: TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color), m_gizmo_scene(2 * (colors.size() + 1)) {}
~TriangleSelectorMmGui() override = default;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render(ImGuiWrapper* imgui, const Transform3d& matrix) override;
+#else
// Render current selection. Transformation matrices are supposed
// to be already set.
void render(ImGuiWrapper* imgui) override;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
private:
void update_render_data();
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
index c90c721cd..18acf6e9b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.cpp
@@ -2,6 +2,9 @@
#include "GLGizmoMove.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "slic3r/GUI/Plater.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#include
@@ -121,7 +124,7 @@ void GLGizmoMove3D::on_render()
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
auto render_grabber_connection = [this, ¢er](unsigned int id) {
if (m_grabbers[id].enabled) {
if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) {
@@ -129,7 +132,7 @@ void GLGizmoMove3D::on_render()
m_grabber_connections[id].model.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.color = AXES_COLOR[id];
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
@@ -139,7 +142,7 @@ void GLGizmoMove3D::on_render()
init_data.add_vertex((Vec3f)m_grabbers[id].center.cast());
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_grabber_connections[id].model.init_from(std::move(init_data));
}
@@ -147,18 +150,28 @@ void GLGizmoMove3D::on_render()
m_grabber_connections[id].model.render();
}
};
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (m_hover_id == -1) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// draw axes
for (unsigned int i = 0; i < 3; ++i) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
render_grabber_connection(i);
#else
if (m_grabbers[i].enabled) {
@@ -168,13 +181,13 @@ void GLGizmoMove3D::on_render()
::glVertex3dv(m_grabbers[i].center.data());
glsafe(::glEnd());
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// draw grabbers
render_grabbers(box);
@@ -185,15 +198,30 @@ void GLGizmoMove3D::on_render()
}
else {
// draw axis
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
render_grabber_connection(m_hover_id);
shader->stop_using();
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
glsafe(::glColor4fv(AXES_COLOR[m_hover_id].data()));
::glBegin(GL_LINES);
@@ -202,12 +230,12 @@ void GLGizmoMove3D::on_render()
glsafe(::glEnd());
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
// draw grabber
- float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0);
+ const float mean_size = (float)((box.size().x() + box.size().y() + box.size().z()) / 3.0);
m_grabbers[m_hover_id].render(true, mean_size);
shader->stop_using();
}
@@ -254,18 +282,22 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box, bool picking)
{
- float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
- double size = m_dragging ? double(m_grabbers[axis].get_dragging_half_size(mean_size)) : double(m_grabbers[axis].get_half_size(mean_size));
+ const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
+ const double size = m_dragging ? double(m_grabbers[axis].get_dragging_half_size(mean_size)) : double(m_grabbers[axis].get_half_size(mean_size));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader == nullptr)
return;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cone.set_color((!picking && m_hover_id != -1) ? complementary(m_grabbers[axis].color) : m_grabbers[axis].color);
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -275,8 +307,21 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ Transform3d view_model_matrix = camera.get_view_matrix() * Geometry::assemble_transform(m_grabbers[axis].center);
+ if (axis == X)
+ view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), 0.5 * PI * Vec3d::UnitY());
+ else if (axis == Y)
+ view_model_matrix = view_model_matrix * Geometry::assemble_transform(Vec3d::Zero(), -0.5 * PI * Vec3d::UnitX());
+ view_model_matrix = view_model_matrix * Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(m_grabbers[axis].center.x(), m_grabbers[axis].center.y(), m_grabbers[axis].center.z()));
if (axis == X)
@@ -286,12 +331,15 @@ void GLGizmoMove3D::render_grabber_extension(Axis axis, const BoundingBoxf3& box
glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cone.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
if (! picking)
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp
index 7c7ee0486..92729c199 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoMove.hpp
@@ -18,14 +18,14 @@ class GLGizmoMove3D : public GLGizmoBase
Vec3d m_starting_box_bottom_center{ Vec3d::Zero() };
GLModel m_cone;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
struct GrabberConnection
{
GLModel model;
Vec3d old_center{ Vec3d::Zero() };
};
std::array m_grabber_connections;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
public:
GLGizmoMove3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
index d3fd294b3..03d60440a 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp
@@ -18,11 +18,11 @@
namespace Slic3r::GUI {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr;
#else
std::shared_ptr GLGizmoPainterBase::s_sphere = nullptr;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
: GLGizmoBase(parent, icon_filename, sprite_id)
@@ -31,13 +31,13 @@ GLGizmoPainterBase::GLGizmoPainterBase(GLCanvas3D& parent, const std::string& ic
GLGizmoPainterBase::~GLGizmoPainterBase()
{
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (s_sphere != nullptr)
s_sphere.reset();
#else
if (s_sphere != nullptr && s_sphere->has_VBOs())
s_sphere->release_geometry();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
void GLGizmoPainterBase::data_changed()
@@ -80,7 +80,11 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl
void GLGizmoPainterBase::render_triangles(const Selection& selection) const
{
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto* shader = wxGetApp().get_shader("gouraud_attr");
+#else
auto* shader = wxGetApp().get_shader("gouraud");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (! shader)
return;
shader->start_using();
@@ -105,8 +109,16 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
if (is_left_handed)
glsafe(::glFrontFace(GL_CW));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d matrix = camera.get_view_matrix() * trafo_matrix;
+ shader->set_uniform("view_model_matrix", matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
// For printers with multiple extruders, it is necessary to pass trafo_matrix
// to the shader input variable print_box.volume_world_matrix before
@@ -114,9 +126,13 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const
// wrong transformation matrix is used for "Clipping of view".
shader->set_uniform("volume_world_matrix", trafo_matrix);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_triangle_selectors[mesh_id]->render(m_imgui, trafo_matrix);
+#else
m_triangle_selectors[mesh_id]->render(m_imgui);
glsafe(::glPopMatrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (is_left_handed)
glsafe(::glFrontFace(GL_CCW));
}
@@ -151,11 +167,25 @@ void GLGizmoPainterBase::render_cursor()
void GLGizmoPainterBase::render_cursor_circle()
{
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
const Camera &camera = wxGetApp().plater()->get_camera();
const float zoom = float(camera.get_zoom());
const float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
- const Size cnv_size = m_parent.get_canvas_size();
+ const Size cnv_size = m_parent.get_canvas_size();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const float cnv_width = float(cnv_size.get_width());
+ const float cnv_height = float(cnv_size.get_height());
+ if (cnv_width == 0.0f || cnv_height == 0.0f)
+ return;
+
+ const float cnv_inv_width = 1.0f / cnv_width;
+ const float cnv_inv_height = 1.0f / cnv_height;
+
+ const Vec2d center = m_parent.get_local_mouse_position();
+ const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom());
+#else
const float cnv_half_width = 0.5f * float(cnv_size.get_width());
const float cnv_half_height = 0.5f * float(cnv_size.get_height());
if (cnv_half_width == 0.0f || cnv_half_height == 0.0f)
@@ -163,14 +193,16 @@ void GLGizmoPainterBase::render_cursor_circle()
const Vec2d mouse_pos(m_parent.get_local_mouse_position().x(), m_parent.get_local_mouse_position().y());
Vec2d center(mouse_pos.x() - cnv_half_width, cnv_half_height - mouse_pos.y());
center = center * inv_zoom;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glLineWidth(1.5f));
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
static const std::array color = { 0.f, 1.f, 0.3f };
glsafe(::glColor3fv(color.data()));
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glDisable(GL_DEPTH_TEST));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
glsafe(::glLoadIdentity());
// ensure that the circle is renderered inside the frustrum
@@ -178,38 +210,57 @@ void GLGizmoPainterBase::render_cursor_circle()
// ensure that the overlay fits the frustrum near z plane
const double gui_scale = camera.get_gui_scale();
glsafe(::glScaled(gui_scale, gui_scale, 1.0));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushAttrib(GL_ENABLE_BIT));
glsafe(::glLineStipple(4, 0xAAAA));
glsafe(::glEnable(GL_LINE_STIPPLE));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) {
+ m_old_cursor_radius = radius;
+#else
if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - m_cursor_radius) > EPSILON) {
- m_old_center = center;
m_old_cursor_radius = m_cursor_radius;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ m_old_center = center;
m_circle.reset();
GLModel::Geometry init_data;
static const unsigned int StepsCount = 32;
static const float StepSize = 2.0f * float(PI) / float(StepsCount);
- init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 };
init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f };
init_data.reserve_vertices(StepsCount);
init_data.reserve_indices(StepsCount);
// vertices + indices
- for (unsigned short i = 0; i < StepsCount; ++i) {
- const float angle = float(i * StepSize);
- init_data.add_vertex(Vec3f(center.x() + ::cos(angle) * m_cursor_radius, center.y() + ::sin(angle) * m_cursor_radius, 0.0f));
- init_data.add_ushort_index(i);
+ for (unsigned int i = 0; i < StepsCount; ++i) {
+ const float angle = float(i) * StepSize;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f),
+ -2.0f * ((center.y() + ::sin(angle) * radius) * cnv_inv_height - 0.5f)));
+#else
+ init_data.add_vertex(Vec2f(center.x() + ::cos(angle) * m_cursor_radius, center.y() + ::sin(angle) * m_cursor_radius));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+ init_data.add_index(i);
}
m_circle.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = GUI::wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader->set_uniform("view_model_matrix", Transform3d::Identity());
+ shader->set_uniform("projection_matrix", Transform3d::Identity());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_circle.render();
shader->stop_using();
}
@@ -218,10 +269,12 @@ void GLGizmoPainterBase::render_cursor_circle()
for (double angle=0; angle<2*M_PI; angle+=M_PI/20.)
::glVertex2f(GLfloat(center.x()+m_cursor_radius*cos(angle)), GLfloat(center.y()+m_cursor_radius*sin(angle)));
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopAttrib());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glEnable(GL_DEPTH_TEST));
}
@@ -229,29 +282,35 @@ void GLGizmoPainterBase::render_cursor_circle()
void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
{
if (s_sphere == nullptr) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
s_sphere = std::make_shared();
s_sphere->init_from(its_make_sphere(1.0, double(PI) / 12.0));
#else
s_sphere = std::make_shared();
s_sphere->load_its_flat_shading(its_make_sphere(1.0, double(PI) / 12.0));
s_sphere->finalize_geometry(true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
const Transform3d complete_scaling_matrix_inverse = Geometry::Transformation(trafo).get_matrix(true, true, false, true).inverse();
const bool is_left_handed = Geometry::Transformation(trafo).is_left_handed();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo.data()));
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glTranslatef(m_rr.hit.x(), m_rr.hit.y(), m_rr.hit.z()));
glsafe(::glMultMatrixd(complete_scaling_matrix_inverse.data()));
glsafe(::glScaled(m_cursor_radius, m_cursor_radius, m_cursor_radius));
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
if (is_left_handed)
glFrontFace(GL_CW);
@@ -261,26 +320,38 @@ void GLGizmoPainterBase::render_cursor_sphere(const Transform3d& trafo) const
render_color = this->get_cursor_sphere_left_button_color();
else if (m_button_down == Button::Right)
render_color = this->get_cursor_sphere_right_button_color();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ Transform3d view_model_matrix = camera.get_view_matrix() * trafo *
+ Geometry::assemble_transform(m_rr.hit.cast()) * complete_scaling_matrix_inverse *
+ Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), m_cursor_radius * Vec3d::Ones());
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
assert(s_sphere != nullptr);
s_sphere->set_color(render_color);
#else
glsafe(::glColor4fv(render_color.data()));
assert(s_sphere != nullptr);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
s_sphere->render();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (is_left_handed)
glFrontFace(GL_CCW);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
@@ -839,7 +910,11 @@ ColorRGBA TriangleSelectorGUI::get_seed_fill_color(const ColorRGBA& base_color)
return saturate(base_color, 0.75f);
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void TriangleSelectorGUI::render(ImGuiWrapper* imgui, const Transform3d& matrix)
+#else
void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
static const ColorRGBA enforcers_color = { 0.47f, 0.47f, 1.0f, 1.0f };
static const ColorRGBA blockers_color = { 1.0f, 0.44f, 0.44f, 1.0f };
@@ -852,12 +927,16 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
auto* shader = wxGetApp().get_current_shader();
if (! shader)
return;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ assert(shader->get_name() == "gouraud_attr");
+#else
assert(shader->get_name() == "gouraud");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
ScopeGuard guard([shader]() { if (shader) shader->set_uniform("offset_depth_buffer", false);});
shader->set_uniform("offset_depth_buffer", true);
for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color),
std::make_pair(&m_iva_blockers, blockers_color)}) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
iva.first->set_color(iva.second);
iva.first->render();
#else
@@ -865,10 +944,10 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
shader->set_uniform("uniform_color", iva.second);
iva.first->render();
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto& iva : m_iva_seed_fills) {
size_t color_idx = &iva - &m_iva_seed_fills.front();
const ColorRGBA& color = TriangleSelectorGUI::get_seed_fill_color(color_idx == 1 ? enforcers_color :
@@ -887,10 +966,14 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
shader->set_uniform("uniform_color", color);
iva.render();
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ render_paint_contour(matrix);
+#else
render_paint_contour();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
if (m_paint_contour.has_VBO()) {
ScopeGuard guard_gouraud([shader]() { shader->start_using(); });
@@ -905,7 +988,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui)
contour_shader->stop_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
if (imgui)
@@ -921,7 +1004,7 @@ void TriangleSelectorGUI::update_render_data()
int blc_cnt = 0;
std::vector seed_fill_cnt(m_iva_seed_fills.size(), 0);
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto* iva : { &m_iva_enforcers, &m_iva_blockers }) {
iva->reset();
}
@@ -931,26 +1014,26 @@ void TriangleSelectorGUI::update_render_data()
}
GLModel::Geometry iva_enforcers_data;
- iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ iva_enforcers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
GLModel::Geometry iva_blockers_data;
- iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ iva_blockers_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
std::array iva_seed_fills_data;
for (auto& data : iva_seed_fills_data)
- data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
+ data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->release_geometry();
for (auto &iva : m_iva_seed_fills)
iva.release_geometry();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (const Triangle &tr : m_triangles) {
if (!tr.valid() || tr.is_split() || (tr.get_state() == EnforcerBlockerType::NONE && !tr.is_selected_by_seed_fill()))
continue;
int tr_state = int(tr.get_state());
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel::Geometry &iva = tr.is_selected_by_seed_fill() ? iva_seed_fills_data[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? iva_enforcers_data :
iva_blockers_data;
@@ -958,7 +1041,7 @@ void TriangleSelectorGUI::update_render_data()
GLIndexedVertexArray &iva = tr.is_selected_by_seed_fill() ? m_iva_seed_fills[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers :
m_iva_blockers;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
int &cnt = tr.is_selected_by_seed_fill() ? seed_fill_cnt[tr_state] :
tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt :
blc_cnt;
@@ -968,21 +1051,21 @@ void TriangleSelectorGUI::update_render_data()
//FIXME the normal may likely be pulled from m_triangle_selectors, but it may not be worth the effort
// or the current implementation may be more cache friendly.
const Vec3f n = (v1 - v0).cross(v2 - v1).normalized();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
iva.add_vertex(v0, n);
iva.add_vertex(v1, n);
iva.add_vertex(v2, n);
- iva.add_uint_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
+ iva.add_triangle((unsigned int)cnt, (unsigned int)cnt + 1, (unsigned int)cnt + 2);
#else
iva.push_geometry(v0, n);
iva.push_geometry(v1, n);
iva.push_geometry(v2, n);
iva.push_triangle(cnt, cnt + 1, cnt + 2);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
cnt += 3;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!iva_enforcers_data.is_empty())
m_iva_enforcers.init_from(std::move(iva_enforcers_data));
if (!iva_blockers_data.is_empty())
@@ -991,17 +1074,15 @@ void TriangleSelectorGUI::update_render_data()
if (!iva_seed_fills_data[i].is_empty())
m_iva_seed_fills[i].init_from(std::move(iva_seed_fills_data[i]));
}
+
+ update_paint_contour();
#else
for (auto *iva : {&m_iva_enforcers, &m_iva_blockers})
iva->finalize_geometry(true);
for (auto &iva : m_iva_seed_fills)
iva.finalize_geometry(true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- update_paint_contour();
-#else
m_paint_contour.release_geometry();
std::vector contour_edges = this->get_seed_fill_contour();
m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6);
@@ -1020,10 +1101,10 @@ void TriangleSelectorGUI::update_render_data()
m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size();
m_paint_contour.finalize_geometry();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
void GLPaintContour::render() const
{
assert(this->m_contour_VBO_id != 0);
@@ -1081,7 +1162,7 @@ void GLPaintContour::release_geometry()
}
this->clear();
}
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
#ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
@@ -1118,60 +1199,60 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
INVALID
};
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (auto& va : m_varrays)
va.reset();
#else
for (auto& va : m_varrays)
va.release_geometry();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
std::array cnts;
::glScalef(1.01f, 1.01f, 1.01f);
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
std::array varrays_data;
for (auto& data : varrays_data)
data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::EIndexType::UINT };
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
for (int tr_id=0; tr_idadd_vertex(m_vertices[tr.verts_idxs[i]].v, Vec3f(0.0f, 0.0f, 1.0f));
}
@@ -1185,36 +1266,46 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
va->push_triangle(*cnt,
*cnt + 1,
*cnt + 2);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
*cnt += 3;
}
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
for (int i = 0; i < 3; ++i) {
if (!varrays_data[i].is_empty())
m_varrays[i].init_from(std::move(varrays_data[i]));
}
#else
- for (auto* iva : { &m_iva_enforcers, &m_iva_blockers })
- iva->finalize_geometry(true);
+// for (auto* iva : { &m_iva_enforcers, &m_iva_blockers })
+// iva->finalize_geometry(true);
+//
+// for (auto& iva : m_iva_seed_fills)
+// iva.finalize_geometry(true);
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
- for (auto& iva : m_iva_seed_fills)
- iva.finalize_geometry(true);
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
-
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
::glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
for (vtype i : {ORIGINAL, SPLIT, INVALID}) {
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel& va = m_varrays[i];
switch (i) {
case ORIGINAL: va.set_color({ 0.0f, 0.0f, 1.0f, 1.0f }); break;
@@ -1233,56 +1324,71 @@ void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui)
}
va.render();
}
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
::glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
if (curr_shader != nullptr)
curr_shader->start_using();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
#endif // PRUSASLICER_TRIANGLE_SELECTOR_DEBUG
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void TriangleSelectorGUI::update_paint_contour()
{
m_paint_contour.reset();
GLModel::Geometry init_data;
const std::vector contour_edges = this->get_seed_fill_contour();
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::index_type(2 * contour_edges.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2 * contour_edges.size());
init_data.reserve_indices(2 * contour_edges.size());
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ init_data.color = ColorRGBA::WHITE();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+//
// vertices + indices
unsigned int vertices_count = 0;
for (const Vec2i& edge : contour_edges) {
init_data.add_vertex(m_vertices[edge(0)].v);
init_data.add_vertex(m_vertices[edge(1)].v);
vertices_count += 2;
- if (init_data.format.index_type == GLModel::Geometry::EIndexType::USHORT)
- init_data.add_ushort_line((unsigned short)vertices_count - 2, (unsigned short)vertices_count - 1);
- else
- init_data.add_uint_line(vertices_count - 2, vertices_count - 1);
+ init_data.add_line(vertices_count - 2, vertices_count - 1);
}
if (!init_data.is_empty())
m_paint_contour.init_from(std::move(init_data));
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void TriangleSelectorGUI::render_paint_contour(const Transform3d& matrix)
+#else
void TriangleSelectorGUI::render_paint_contour()
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
{
auto* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto* contour_shader = wxGetApp().get_shader("mm_contour_attr");
+#else
auto* contour_shader = wxGetApp().get_shader("mm_contour");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (contour_shader != nullptr) {
contour_shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ contour_shader->set_uniform("view_model_matrix", camera.get_view_matrix() * matrix);
+ contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
glsafe(::glDepthFunc(GL_LEQUAL));
m_paint_contour.render();
glsafe(::glDepthFunc(GL_LESS));
@@ -1293,6 +1399,6 @@ void TriangleSelectorGUI::render_paint_contour()
if (curr_shader != nullptr)
curr_shader->start_using();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
} // namespace Slic3r::GUI
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp
index 7949e2657..64f531793 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp
@@ -3,11 +3,11 @@
#include "GLGizmoBase.hpp"
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GLModel.hpp"
#else
#include "slic3r/GUI/3DScene.hpp"
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "libslic3r/ObjectID.hpp"
#include "libslic3r/TriangleSelector.hpp"
@@ -33,7 +33,7 @@ enum class PainterGizmoType {
MMU_SEGMENTATION
};
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
class GLPaintContour
{
public:
@@ -69,7 +69,7 @@ public:
GLuint m_contour_VBO_id{0};
GLuint m_contour_EBO_id{0};
};
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
class TriangleSelectorGUI : public TriangleSelector {
public:
@@ -77,10 +77,15 @@ public:
: TriangleSelector(mesh) {}
virtual ~TriangleSelectorGUI() = default;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ virtual void render(ImGuiWrapper* imgui, const Transform3d& matrix);
+ void render(const Transform3d& matrix) { this->render(nullptr, matrix); }
+#else
// Render current selection. Transformation matrices are supposed
// to be already set.
virtual void render(ImGuiWrapper *imgui);
void render() { this->render(nullptr); }
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void request_update_render_data() { m_update_render_data = true; }
@@ -98,7 +103,7 @@ protected:
private:
void update_render_data();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_iva_enforcers;
GLModel m_iva_blockers;
std::array m_iva_seed_fills;
@@ -110,17 +115,21 @@ private:
GLIndexedVertexArray m_iva_blockers;
std::array m_iva_seed_fills;
std::array m_varrays;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
protected:
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_paint_contour;
void update_paint_contour();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_paint_contour(const Transform3d& matrix);
+#else
void render_paint_contour();
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
GLPaintContour m_paint_contour;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
};
@@ -203,11 +212,11 @@ protected:
bool m_paint_on_overhangs_only = false;
float m_highlight_by_angle_threshold_deg = 0.f;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_circle;
Vec2d m_old_center{ Vec2d::Zero() };
float m_old_cursor_radius{ 0.0f };
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
static constexpr float SmartFillAngleMin = 0.0f;
static constexpr float SmartFillAngleMax = 90.f;
@@ -241,11 +250,11 @@ private:
const Camera& camera,
const std::vector& trafo_matrices) const;
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
static std::shared_ptr s_sphere;
#else
static std::shared_ptr s_sphere;
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
bool m_internal_stack_active = false;
bool m_schedule_update = false;
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
index c97a4a788..1d817b58b 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.cpp
@@ -163,15 +163,30 @@ void GLGizmoRotate::on_render()
glsafe(::glEnable(GL_DEPTH_TEST));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_grabbers.front().matrix = local_transform(selection);
+#else
glsafe(::glPushMatrix());
transform_to_local(selection);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
const bool radius_changed = std::abs(m_old_radius - m_radius) > EPSILON;
m_old_radius = m_radius;
@@ -205,12 +220,14 @@ void GLGizmoRotate::on_render()
if (m_hover_id != -1)
render_angle();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
render_grabber(box);
render_grabber_extension(box, false);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLGizmoRotate::on_render_for_picking()
@@ -219,15 +236,20 @@ void GLGizmoRotate::on_render_for_picking()
glsafe(::glDisable(GL_DEPTH_TEST));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ m_grabbers.front().matrix = local_transform(selection);
+#else
glsafe(::glPushMatrix());
-
transform_to_local(selection);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
const BoundingBoxf3& box = selection.get_bounding_box();
render_grabbers_for_picking(box);
render_grabber_extension(box, true);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
void GLGizmoRotate3D::on_render_input_window(float x, float y, float bottom_limit)
@@ -260,26 +282,26 @@ void GLGizmoRotate3D::load_rotoptimize_state()
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_circle(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_circle() const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_circle.is_initialized() || radius_changed) {
m_circle.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(ScaleStepsCount);
init_data.reserve_indices(ScaleStepsCount);
// vertices + indices
- for (unsigned short i = 0; i < ScaleStepsCount; ++i) {
+ for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
const float angle = float(i * ScaleStepRad);
init_data.add_vertex(Vec3f(::cos(angle) * m_radius, ::sin(angle) * m_radius, 0.0f));
- init_data.add_ushort_index(i);
+ init_data.add_index(i);
}
m_circle.init_from(std::move(init_data));
@@ -297,29 +319,29 @@ void GLGizmoRotate::render_circle() const
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_scale(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_scale() const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float out_radius_long = m_snap_fine_out_radius;
const float out_radius_short = m_radius * (1.0f + 0.5f * ScaleLongTooth);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_scale.is_initialized() || radius_changed) {
m_scale.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2 * ScaleStepsCount);
init_data.reserve_indices(2 * ScaleStepsCount);
// vertices + indices
- for (unsigned short i = 0; i < ScaleStepsCount; ++i) {
+ for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
const float angle = float(i * ScaleStepRad);
const float cosa = ::cos(angle);
const float sina = ::sin(angle);
@@ -328,10 +350,12 @@ void GLGizmoRotate::render_scale() const
const float out_x = (i % ScaleLongEvery == 0) ? cosa * out_radius_long : cosa * out_radius_short;
const float out_y = (i % ScaleLongEvery == 0) ? sina * out_radius_long : sina * out_radius_short;
+ // vertices
init_data.add_vertex(Vec3f(in_x, in_y, 0.0f));
init_data.add_vertex(Vec3f(out_x, out_y, 0.0f));
- init_data.add_ushort_index(i * 2);
- init_data.add_ushort_index(i * 2 + 1);
+
+ // indices
+ init_data.add_line(i * 2, i * 2 + 1);
}
m_scale.init_from(std::move(init_data));
@@ -355,30 +379,30 @@ void GLGizmoRotate::render_scale() const
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_snap_radii(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_snap_radii() const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float step = 2.0f * float(PI) / float(SnapRegionsCount);
const float in_radius = m_radius / 3.0f;
const float out_radius = 2.0f * in_radius;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
if (!m_snap_radii.is_initialized() || radius_changed) {
m_snap_radii.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2 * ScaleStepsCount);
init_data.reserve_indices(2 * ScaleStepsCount);
// vertices + indices
- for (unsigned short i = 0; i < ScaleStepsCount; ++i) {
+ for (unsigned int i = 0; i < ScaleStepsCount; ++i) {
const float angle = float(i * step);
const float cosa = ::cos(angle);
const float sina = ::sin(angle);
@@ -387,10 +411,12 @@ void GLGizmoRotate::render_snap_radii() const
const float out_x = cosa * out_radius;
const float out_y = sina * out_radius;
+ // vertices
init_data.add_vertex(Vec3f(in_x, in_y, 0.0f));
init_data.add_vertex(Vec3f(out_x, out_y, 0.0f));
- init_data.add_ushort_index(i * 2);
- init_data.add_ushort_index(i * 2 + 1);
+
+ // indices
+ init_data.add_line(i * 2, i * 2 + 1);
}
m_snap_radii.init_from(std::move(init_data));
@@ -414,17 +440,17 @@ void GLGizmoRotate::render_snap_radii() const
::glVertex3f((GLfloat)out_x, (GLfloat)out_y, (GLfloat)out_z);
}
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_changed)
{
if (!m_reference_radius.is_initialized() || radius_changed) {
m_reference_radius.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
@@ -433,7 +459,7 @@ void GLGizmoRotate::render_reference_radius(const ColorRGBA& color, bool radius_
init_data.add_vertex(Vec3f(m_radius * (1.0f + GrabberOffset), 0.0f, 0.0f));
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_reference_radius.init_from(std::move(init_data));
}
@@ -449,34 +475,38 @@ void GLGizmoRotate::render_reference_radius() const
::glVertex3f((GLfloat)(m_radius * (1.0f + GrabberOffset)), 0.0f, 0.0f);
glsafe(::glEnd());
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_angle_arc(const ColorRGBA& color, bool radius_changed)
#else
void GLGizmoRotate::render_angle() const
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
const float step_angle = float(m_angle) / float(AngleResolution);
const float ex_radius = m_radius * (1.0f + GrabberOffset);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
- if (!m_angle_arc.is_initialized() || radius_changed) {
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ const bool angle_changed = std::abs(m_old_angle - m_angle) > EPSILON;
+ m_old_angle = m_angle;
+
+ if (!m_angle_arc.is_initialized() || radius_changed || angle_changed) {
m_angle_arc.reset();
+ if (m_angle > 0.0f) {
+ GLModel::Geometry init_data;
+ init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3 };
+ init_data.reserve_vertices(1 + AngleResolution);
+ init_data.reserve_indices(1 + AngleResolution);
- GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::LineStrip, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
- init_data.reserve_vertices(1 + AngleResolution);
- init_data.reserve_indices(1 + AngleResolution);
+ // vertices + indices
+ for (unsigned int i = 0; i <= AngleResolution; ++i) {
+ const float angle = float(i) * step_angle;
+ init_data.add_vertex(Vec3f(::cos(angle) * ex_radius, ::sin(angle) * ex_radius, 0.0f));
+ init_data.add_index(i);
+ }
- // vertices + indices
- for (unsigned short i = 0; i <= AngleResolution; ++i) {
- const float angle = float(i) * step_angle;
- init_data.add_vertex(Vec3f(::cos(angle) * ex_radius, ::sin(angle) * ex_radius, 0.0f));
- init_data.add_ushort_index(i);
+ m_angle_arc.init_from(std::move(init_data));
}
-
- m_angle_arc.init_from(std::move(init_data));
}
m_angle_arc.set_color(color);
@@ -491,10 +521,10 @@ void GLGizmoRotate::render_angle() const
::glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
glsafe(::glEnd());
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radius_changed)
{
if (!m_grabber_connection.model.is_initialized() || radius_changed || !m_grabber_connection.old_center.isApprox(m_grabbers.front().center)) {
@@ -502,7 +532,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
m_grabber_connection.old_center = m_grabbers.front().center;
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
@@ -511,7 +541,7 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
init_data.add_vertex((Vec3f)m_grabbers.front().center.cast());
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_grabber_connection.model.init_from(std::move(init_data));
}
@@ -519,11 +549,11 @@ void GLGizmoRotate::render_grabber_connection(const ColorRGBA& color, bool radiu
m_grabber_connection.model.set_color(color);
m_grabber_connection.model.render();
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoRotate::render_grabber(const BoundingBoxf3& box)
{
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
const double grabber_radius = double(m_radius) * (1.0 + double(GrabberOffset));
m_grabbers[0].center = Vec3d(::cos(m_angle) * grabber_radius, ::sin(m_angle) * grabber_radius, 0.0);
m_grabbers[0].angles.z() = m_angle;
@@ -534,7 +564,7 @@ void GLGizmoRotate::render_grabber(const BoundingBoxf3& box)
::glVertex3f(0.0f, 0.0f, 0.0f);
::glVertex3dv(m_grabbers[0].center.data());
glsafe(::glEnd());
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
m_grabbers.front().color = m_highlight_color;
render_grabbers(box);
@@ -545,8 +575,12 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
const float mean_size = float((box.size().x() + box.size().y() + box.size().z()) / 3.0);
const double size = m_dragging ? double(m_grabbers.front().get_dragging_half_size(mean_size)) : double(m_grabbers.front().get_half_size(mean_size));
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat_attr" : "gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -564,17 +598,38 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const Vec3d& center = m_grabbers.front().center;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d& view_matrix = camera.get_view_matrix();
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+
+ Transform3d view_model_matrix = view_matrix * m_grabbers.front().matrix *
+ Geometry::assemble_transform(center, Vec3d(0.5 * PI, 0.0, m_angle)) *
+ Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
glsafe(::glTranslated(center.x(), center.y(), center.z()));
glsafe(::glRotated(Geometry::rad2deg(m_angle), 0.0, 0.0, 1.0));
glsafe(::glRotated(90.0, 1.0, 0.0, 0.0));
glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cone.render();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ view_model_matrix = view_matrix * m_grabbers.front().matrix *
+ Geometry::assemble_transform(center, Vec3d(-0.5 * PI, 0.0, m_angle)) *
+ Geometry::assemble_transform(2.0 * size * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(0.75 * size, 0.75 * size, 3.0 * size));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPopMatrix());
glsafe(::glPushMatrix());
glsafe(::glTranslated(center.x(), center.y(), center.z()));
@@ -582,15 +637,49 @@ void GLGizmoRotate::render_grabber_extension(const BoundingBoxf3& box, bool pick
glsafe(::glRotated(-90.0, 1.0, 0.0, 0.0));
glsafe(::glTranslated(0.0, 0.0, 2.0 * size));
glsafe(::glScaled(0.75 * size, 0.75 * size, 3.0 * size));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cone.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
-#if !ENABLE_GLBEGIN_GLEND_REMOVAL
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
if (! picking)
-#endif // !ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
shader->stop_using();
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+Transform3d GLGizmoRotate::local_transform(const Selection& selection) const
+{
+ Transform3d ret;
+
+ switch (m_axis)
+ {
+ case X:
+ {
+ ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.5 * PI, 0.0)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI));
+ break;
+ }
+ case Y:
+ {
+ ret = Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, 0.0, -0.5 * PI)) * Geometry::assemble_transform(Vec3d::Zero(), Vec3d(0.0, -0.5 * PI, 0.0));
+ break;
+ }
+ default:
+ case Z:
+ {
+ ret = Transform3d::Identity();
+ break;
+ }
+ }
+
+ if (selection.is_single_volume() || selection.is_single_modifier() || selection.requires_local_axes())
+ ret = selection.get_volume(*selection.get_volume_idxs().begin())->get_instance_transformation().get_matrix(true, false, true, true) * ret;
+
+ return Geometry::assemble_transform(m_center) * ret;
+}
+#else
void GLGizmoRotate::transform_to_local(const Selection& selection) const
{
glsafe(::glTranslated(m_center.x(), m_center.y(), m_center.z()));
@@ -622,6 +711,7 @@ void GLGizmoRotate::transform_to_local(const Selection& selection) const
}
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
Vec3d GLGizmoRotate::mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const
{
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
index 02dd84e68..b58fde1ee 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoRotate.hpp
@@ -36,7 +36,7 @@ private:
float m_snap_fine_out_radius{ 0.0f };
GLModel m_cone;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
GLModel m_circle;
GLModel m_scale;
GLModel m_snap_radii;
@@ -50,7 +50,8 @@ private:
GrabberConnection m_grabber_connection;
float m_old_radius{ 0.0f };
float m_old_hover_radius{ 0.0f };
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+ float m_old_angle{ 0.0f };
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA m_drag_color;
ColorRGBA m_highlight_color;
@@ -88,7 +89,7 @@ protected:
void on_render_for_picking() override;
private:
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_circle(const ColorRGBA& color, bool radius_changed);
void render_scale(const ColorRGBA& color, bool radius_changed);
void render_snap_radii(const ColorRGBA& color, bool radius_changed);
@@ -101,11 +102,16 @@ private:
void render_snap_radii() const;
void render_reference_radius() const;
void render_angle() const;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void render_grabber(const BoundingBoxf3& box);
void render_grabber_extension(const BoundingBoxf3& box, bool picking);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ Transform3d local_transform(const Selection& selection) const;
+#else
void transform_to_local(const Selection& selection) const;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
// returns the intersection of the mouse ray with the plane perpendicular to the gizmo axis, in local coordinate
Vec3d mouse_position_in_local_plane(const Linef3& mouse_ray, const Selection& selection) const;
};
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
index f7565a483..373a2396d 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp
@@ -2,6 +2,9 @@
#include "GLGizmoScale.hpp"
#include "slic3r/GUI/GLCanvas3D.hpp"
#include "slic3r/GUI/GUI_App.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "slic3r/GUI/Plater.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#include
@@ -22,7 +25,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
, m_drag_color(DEFAULT_DRAG_COLOR)
, m_highlight_color(DEFAULT_HIGHLIGHT_COLOR)
{
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_grabber_connections[0].grabber_indices = { 0, 1 };
m_grabber_connections[1].grabber_indices = { 2, 3 };
m_grabber_connections[2].grabber_indices = { 4, 5 };
@@ -30,7 +33,7 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
m_grabber_connections[4].grabber_indices = { 7, 8 };
m_grabber_connections[5].grabber_indices = { 8, 9 };
m_grabber_connections[6].grabber_indices = { 9, 6 };
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
std::string GLGizmoScale3D::get_tooltip() const
@@ -215,11 +218,11 @@ void GLGizmoScale3D::on_render()
m_box = selection.get_bounding_box();
const Vec3d& center = m_box.center();
- Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
- Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
- Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
+ const Vec3d offset_x = offsets_transform * Vec3d((double)Offset, 0.0, 0.0);
+ const Vec3d offset_y = offsets_transform * Vec3d(0.0, (double)Offset, 0.0);
+ const Vec3d offset_z = offsets_transform * Vec3d(0.0, 0.0, (double)Offset);
- bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
+ const bool ctrl_down = (m_dragging && m_starting.ctrl_down) || (!m_dragging && wxGetKeyState(WXK_CONTROL));
// x axis
m_grabbers[0].center = m_transform * Vec3d(m_box.min.x(), center.y(), center.z()) - offset_x;
@@ -257,14 +260,23 @@ void GLGizmoScale3D::on_render()
const BoundingBoxf3& selection_box = selection.get_bounding_box();
- float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
+ const float grabber_mean_size = (float)((selection_box.size().x() + selection_box.size().y() + selection_box.size().z()) / 3.0);
if (m_hover_id == -1) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (m_grabbers[0].enabled && m_grabbers[1].enabled)
render_grabbers_connection(0, 1, m_grabbers[0].color);
if (m_grabbers[2].enabled && m_grabbers[3].enabled)
@@ -296,23 +308,36 @@ void GLGizmoScale3D::on_render()
render_grabbers_connection(7, 8);
render_grabbers_connection(8, 9);
render_grabbers_connection(9, 6);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
// draw grabbers
render_grabbers(grabber_mean_size);
}
else if (m_hover_id == 0 || m_hover_id == 1) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
render_grabbers_connection(0, 1, m_grabbers[0].color);
shader->stop_using();
}
// draw grabbers
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
// draw connection
glsafe(::glColor4fv(m_grabbers[0].color.data()));
@@ -320,7 +345,7 @@ void GLGizmoScale3D::on_render()
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -330,17 +355,30 @@ void GLGizmoScale3D::on_render()
}
}
else if (m_hover_id == 2 || m_hover_id == 3) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
render_grabbers_connection(2, 3, m_grabbers[2].color);
shader->stop_using();
}
// draw grabbers
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
// draw connection
glsafe(::glColor4fv(m_grabbers[2].color.data()));
@@ -348,7 +386,7 @@ void GLGizmoScale3D::on_render()
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -358,17 +396,30 @@ void GLGizmoScale3D::on_render()
}
}
else if (m_hover_id == 4 || m_hover_id == 5) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
render_grabbers_connection(4, 5, m_grabbers[4].color);
shader->stop_using();
}
// draw grabbers
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
// draw connection
glsafe(::glColor4fv(m_grabbers[4].color.data()));
@@ -376,7 +427,7 @@ void GLGizmoScale3D::on_render()
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -386,11 +437,20 @@ void GLGizmoScale3D::on_render()
}
}
else if (m_hover_id >= 6) {
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// draw connections
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
render_grabbers_connection(6, 7, m_drag_color);
render_grabbers_connection(7, 8, m_drag_color);
render_grabbers_connection(8, 9, m_drag_color);
@@ -399,7 +459,11 @@ void GLGizmoScale3D::on_render()
}
// draw grabbers
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#else
// draw connection
glsafe(::glColor4fv(m_drag_color.data()));
@@ -410,7 +474,7 @@ void GLGizmoScale3D::on_render()
// draw grabbers
GLShaderProgram* shader = wxGetApp().get_shader("gouraud_light");
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
if (shader != nullptr) {
shader->start_using();
shader->set_uniform("emission_factor", 0.1f);
@@ -428,7 +492,7 @@ void GLGizmoScale3D::on_render_for_picking()
render_grabbers_for_picking(m_parent.get_selection().get_bounding_box());
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color)
{
auto grabber_connection = [this](unsigned int id_1, unsigned int id_2) {
@@ -451,7 +515,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
m_grabber_connections[id].model.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3, GLModel::Geometry::EIndexType::USHORT };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3 };
init_data.reserve_vertices(2);
init_data.reserve_indices(2);
@@ -460,7 +524,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
init_data.add_vertex((Vec3f)m_grabbers[id_2].center.cast());
// indices
- init_data.add_ushort_line(0, 1);
+ init_data.add_line(0, 1);
m_grabber_connections[id].model.init_from(std::move(init_data));
}
@@ -479,7 +543,7 @@ void GLGizmoScale3D::render_grabbers_connection(unsigned int id_1, unsigned int
glsafe(::glEnd());
}
}
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
{
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
index e0a49cdbf..f4efe052a 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.hpp
@@ -33,7 +33,7 @@ class GLGizmoScale3D : public GLGizmoBase
double m_snap_step{ 0.05 };
StartingData m_starting;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
struct GrabberConnection
{
GLModel model;
@@ -42,7 +42,7 @@ class GLGizmoScale3D : public GLGizmoBase
Vec3d old_v2{ Vec3d::Zero() };
};
std::array m_grabber_connections;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
ColorRGBA m_base_color;
ColorRGBA m_drag_color;
@@ -77,11 +77,11 @@ protected:
virtual void on_render_for_picking() override;
private:
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void render_grabbers_connection(unsigned int id_1, unsigned int id_2, const ColorRGBA& color);
#else
void render_grabbers_connection(unsigned int id_1, unsigned int id_2) const;
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
void do_scale_along_axis(Axis axis, const UpdateData& data);
void do_scale_uniform(const UpdateData& data);
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
index 1b4c751d4..1a383187c 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSimplify.cpp
@@ -651,7 +651,7 @@ void GLGizmoSimplify::init_model()
}
assert(volume != nullptr);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
// set actual triangle count
m_triangle_count += volume->mesh().its.indices.size();
#else
@@ -659,17 +659,17 @@ void GLGizmoSimplify::init_model()
// set actual triangle count
m_triangle_count += its.indices.size();
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
assert(m_glmodels.find(id) == m_glmodels.end());
GLModel &glmodel = m_glmodels[id]; // create new glmodel
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.init_from(volume->mesh());
glmodel.set_color(selected_volume->color);
#else
glmodel.init_from(its);
glmodel.set_color(-1,selected_volume->color);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_parent.toggle_model_objects_visibility(false, info->model_object(),
info->get_active_instance(),
@@ -698,11 +698,11 @@ void GLGizmoSimplify::update_model(const State::Data &data)
// when not reset it keeps old shape
glmodel.reset();
glmodel.init_from(its);
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
glmodel.set_color(color);
#else
glmodel.set_color(-1, color);
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
m_triangle_count += its.indices.size();
}
@@ -737,27 +737,53 @@ void GLGizmoSimplify::on_render()
GLModel &glmodel = it->second;
const Transform3d trafo_matrix = selected_volume->world_matrix();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto* gouraud_shader = wxGetApp().get_shader("gouraud_light_attr");
+#else
glsafe(::glPushMatrix());
glsafe(::glMultMatrixd(trafo_matrix.data()));
auto *gouraud_shader = wxGetApp().get_shader("gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushAttrib(GL_DEPTH_TEST));
glsafe(::glEnable(GL_DEPTH_TEST));
gouraud_shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d view_model_matrix = camera.get_view_matrix() * trafo_matrix;
+ gouraud_shader->set_uniform("view_model_matrix", view_model_matrix);
+ gouraud_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ gouraud_shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glmodel.render();
gouraud_shader->stop_using();
if (m_show_wireframe) {
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ auto* contour_shader = wxGetApp().get_shader("mm_contour_attr");
+#else
auto *contour_shader = wxGetApp().get_shader("mm_contour");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
contour_shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ contour_shader->set_uniform("view_model_matrix", view_model_matrix);
+ contour_shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+ const ColorRGBA color = glmodel.get_color();
+ glmodel.set_color(ColorRGBA::WHITE());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glLineWidth(1.0f));
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
glmodel.render();
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ glmodel.set_color(color);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
contour_shader->stop_using();
}
glsafe(::glPopAttrib());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
index 4be0f5a63..3173cb10d 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp
@@ -120,17 +120,21 @@ void GLGizmoSlaSupports::on_render_for_picking()
void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
{
- size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size();
+ const size_t cache_size = m_editing_mode ? m_editing_cache.size() : m_normal_cache.size();
- bool has_points = (cache_size != 0);
- bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh()
+ const bool has_points = (cache_size != 0);
+ const bool has_holes = (! m_c->hollowed_mesh()->get_hollowed_mesh()
&& ! m_c->selection_info()->model_object()->sla_drain_holes.empty());
if (! has_points && ! has_holes)
return;
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = picking ? wxGetApp().get_shader("flat_attr") : wxGetApp().get_shader("gouraud_light_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader(picking ? "flat" : "gouraud_light");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader == nullptr)
return;
@@ -144,21 +148,31 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
if (shader != nullptr)
shader->stop_using();
});
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
const GLVolume* vol = selection.get_volume(*selection.get_volume_idxs().begin());
- const Transform3d& instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
- const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
- float z_shift = m_c->selection_info()->get_sla_shift();
+ const Transform3d instance_scaling_matrix_inverse = vol->get_instance_transformation().get_matrix(true, true, false, true).inverse();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d instance_matrix = Geometry::assemble_transform(m_c->selection_info()->get_sla_shift() * Vec3d::UnitZ()) * vol->get_instance_transformation().get_matrix();
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ const Transform3d& view_matrix = camera.get_view_matrix();
+ const Transform3d& projection_matrix = camera.get_projection_matrix();
+
+ shader->set_uniform("projection_matrix", projection_matrix);
+#else
+ const Transform3d& instance_matrix = vol->get_instance_transformation().get_matrix();
+
+ const float z_shift = m_c->selection_info()->get_sla_shift();
glsafe(::glPushMatrix());
glsafe(::glTranslated(0.0, 0.0, z_shift));
glsafe(::glMultMatrixd(instance_matrix.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
ColorRGBA render_color;
for (size_t i = 0; i < cache_size; ++i) {
const sla::SupportPoint& support_point = m_editing_mode ? m_editing_cache[i].support_point : m_normal_cache[i];
- const bool& point_selected = m_editing_mode ? m_editing_cache[i].selected : false;
+ const bool point_selected = m_editing_mode ? m_editing_cache[i].selected : false;
if (is_mesh_point_clipped(support_point.pos.cast()))
continue;
@@ -185,7 +199,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
}
}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cone.set_color(render_color);
m_sphere.set_color(render_color);
if (!picking)
@@ -193,13 +207,17 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
m_cone.set_color(-1, render_color);
m_sphere.set_color(-1, render_color);
if (shader && !picking)
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("emission_factor", 0.5f);
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d support_matrix = Geometry::assemble_transform(support_point.pos.cast()) * instance_scaling_matrix_inverse;
+#else
glsafe(::glPushMatrix());
- glsafe(::glTranslatef(support_point.pos(0), support_point.pos(1), support_point.pos(2)));
+ glsafe(::glTranslatef(support_point.pos.x(), support_point.pos.y(), support_point.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (vol->is_left_handed())
glFrontFace(GL_CW);
@@ -212,76 +230,108 @@ void GLGizmoSlaSupports::render_points(const Selection& selection, bool picking)
m_c->raycaster()->raycaster()->get_closest_point(m_editing_cache[i].support_point.pos, &m_editing_cache[i].normal);
Eigen::Quaterniond q;
- q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast());
- Eigen::AngleAxisd aa(q);
- glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
-
+ q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * m_editing_cache[i].normal.cast());
+ const Eigen::AngleAxisd aa(q);
const double cone_radius = 0.25; // mm
const double cone_height = 0.75;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix * Transform3d(aa.toRotationMatrix()) *
+ Geometry::assemble_transform((cone_height + support_point.head_front_radius * RenderPointScale) * Vec3d::UnitZ(),
+ Vec3d(PI, 0.0, 0.0), Vec3d(cone_radius, cone_radius, cone_height));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
+ glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
glsafe(::glTranslatef(0.f, 0.f, cone_height + support_point.head_front_radius * RenderPointScale));
- glsafe(::glPushMatrix());
glsafe(::glRotated(180., 1., 0., 0.));
glsafe(::glScaled(cone_radius, cone_radius, cone_height));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cone.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
- glsafe(::glTranslatef(0.f, 0.f, cone_height));
- glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
+ const double radius = (double)support_point.head_front_radius * RenderPointScale;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d view_model_matrix = view_matrix * instance_matrix * support_matrix *
+ Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), radius * Vec3d::Ones());
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
glsafe(::glPushMatrix());
- double radius = (double)support_point.head_front_radius * RenderPointScale;
glsafe(::glScaled(radius, radius, radius));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_sphere.render();
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
if (vol->is_left_handed())
glFrontFace(GL_CCW);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
// Now render the drain holes:
if (has_holes && ! picking) {
render_color = { 0.7f, 0.7f, 0.7f, 0.7f };
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_cylinder.set_color(render_color);
#else
m_cylinder.set_color(-1, render_color);
- if (shader != nu)
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+ if (shader != nullptr)
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
shader->set_uniform("emission_factor", 0.5f);
for (const sla::DrainHole& drain_hole : m_c->selection_info()->model_object()->sla_drain_holes) {
if (is_mesh_point_clipped(drain_hole.pos.cast()))
continue;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d hole_matrix = Geometry::assemble_transform(drain_hole.pos.cast()) * instance_scaling_matrix_inverse;
+#else
// Inverse matrix of the instance scaling is applied so that the mark does not scale with the object.
glsafe(::glPushMatrix());
- glsafe(::glTranslatef(drain_hole.pos(0), drain_hole.pos(1), drain_hole.pos(2)));
+ glsafe(::glTranslatef(drain_hole.pos.x(), drain_hole.pos.y(), drain_hole.pos.z()));
glsafe(::glMultMatrixd(instance_scaling_matrix_inverse.data()));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (vol->is_left_handed())
glFrontFace(GL_CW);
// Matrices set, we can render the point mark now.
-
Eigen::Quaterniond q;
- q.setFromTwoVectors(Vec3d{0., 0., 1.}, instance_scaling_matrix_inverse * (-drain_hole.normal).cast());
- Eigen::AngleAxisd aa(q);
- glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis()(0), aa.axis()(1), aa.axis()(2)));
- glsafe(::glPushMatrix());
+ q.setFromTwoVectors(Vec3d::UnitZ(), instance_scaling_matrix_inverse * (-drain_hole.normal).cast());
+ const Eigen::AngleAxisd aa(q);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Transform3d view_model_matrix = view_matrix * instance_matrix * hole_matrix * Transform3d(aa.toRotationMatrix()) *
+ Geometry::assemble_transform(-drain_hole.height * Vec3d::UnitZ(), Vec3d::Zero(), Vec3d(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
+
+ shader->set_uniform("view_model_matrix", view_model_matrix);
+ shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
+#else
+ glsafe(::glRotated(aa.angle() * (180. / M_PI), aa.axis().x(), aa.axis().y(), aa.axis().z()));
glsafe(::glTranslated(0., 0., -drain_hole.height));
glsafe(::glScaled(drain_hole.radius, drain_hole.radius, drain_hole.height + sla::HoleStickOutLength));
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_cylinder.render();
- glsafe(::glPopMatrix());
if (vol->is_left_handed())
glFrontFace(GL_CCW);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
}
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
index 1e49ebc8c..0d6ec1eb0 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosCommon.cpp
@@ -209,27 +209,32 @@ void InstancesHider::render_cut() const
ClippingPlane clp = *get_pool()->object_clipper()->get_clipping_plane();
clp.set_normal(-clp.get_normal());
clipper->set_limiting_plane(clp);
- } else
+ }
+ else
clipper->set_limiting_plane(ClippingPlane::ClipsNothing());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
-#if !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
+#if !ENABLE_LEGACY_OPENGL_REMOVAL
if (mv->is_model_part())
glsafe(::glColor3f(0.8f, 0.3f, 0.0f));
else {
const ColorRGBA color = color_from_model_volume(*mv);
glsafe(::glColor4fv(color.data()));
}
-#endif // !ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPushAttrib(GL_DEPTH_TEST));
glsafe(::glDisable(GL_DEPTH_TEST));
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
clipper->render_cut(mv->is_model_part() ? ColorRGBA(0.8f, 0.3f, 0.0f, 1.0f) : color_from_model_volume(*mv));
#else
clipper->render_cut();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
glsafe(::glPopAttrib());
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
++clipper_id;
}
@@ -410,11 +415,11 @@ void ObjectClipper::render_cut() const
return;
const SelectionInfo* sel_info = get_pool()->selection_info();
const ModelObject* mo = sel_info->model_object();
- Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
+ const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
size_t clipper_id = 0;
for (const ModelVolume* mv : mo->volumes) {
- Geometry::Transformation vol_trafo = mv->get_transformation();
+ const Geometry::Transformation vol_trafo = mv->get_transformation();
Geometry::Transformation trafo = inst_trafo * vol_trafo;
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
@@ -422,14 +427,18 @@ void ObjectClipper::render_cut() const
clipper->set_plane(*m_clp);
clipper->set_transformation(trafo);
clipper->set_limiting_plane(ClippingPlane(Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_LEGACY_OPENGL_REMOVAL
clipper->render_cut({ 1.0f, 0.37f, 0.0f, 1.0f });
#else
glsafe(::glColor3f(1.0f, 0.37f, 0.0f));
clipper->render_cut();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
++clipper_id;
}
@@ -520,7 +529,7 @@ void SupportsClipper::render_cut() const
const SelectionInfo* sel_info = get_pool()->selection_info();
const ModelObject* mo = sel_info->model_object();
- Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
+ const Geometry::Transformation inst_trafo = mo->instances[sel_info->get_active_instance()]->get_transformation();
//Geometry::Transformation vol_trafo = mo->volumes.front()->get_transformation();
Geometry::Transformation trafo = inst_trafo;// * vol_trafo;
trafo.set_offset(trafo.get_offset() + Vec3d(0., 0., sel_info->get_sla_shift()));
@@ -539,14 +548,18 @@ void SupportsClipper::render_cut() const
m_clipper->set_plane(*ocl->get_clipping_plane());
m_clipper->set_transformation(supports_trafo);
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPushMatrix());
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_clipper->render_cut({ 1.0f, 0.f, 0.37f, 1.0f });
#else
glsafe(::glColor3f(1.0f, 0.f, 0.37f));
m_clipper->render_cut();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
+#if !ENABLE_GL_SHADERS_ATTRIBUTES
glsafe(::glPopMatrix());
+#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
}
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
index 7df2999f1..21b55ea69 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.cpp
@@ -124,7 +124,17 @@ bool GLGizmosManager::init()
return true;
}
-bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_texture)
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+bool GLGizmosManager::init_arrow(const std::string& filename)
+{
+ if (m_arrow_texture.get_id() != 0)
+ return true;
+
+ const std::string path = resources_dir() + "/icons/";
+ return (!filename.empty()) ? m_arrow_texture.load_from_svg_file(path + filename, false, false, false, 512) : false;
+}
+#else
+bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata & arrow_texture)
{
if (m_arrow_texture.texture.get_id() != 0)
return true;
@@ -139,6 +149,7 @@ bool GLGizmosManager::init_arrow(const BackgroundTexture::Metadata& arrow_textur
return res;
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
void GLGizmosManager::set_overlay_icon_size(float size)
{
@@ -329,7 +340,7 @@ void GLGizmosManager::render_current_gizmo_for_picking_pass() const
m_gizmos[m_current]->render_for_picking();
}
-void GLGizmosManager::render_overlay() const
+void GLGizmosManager::render_overlay()
{
if (!m_enabled)
return;
@@ -665,6 +676,60 @@ void GLGizmosManager::update_after_undo_redo(const UndoRedo::Snapshot& snapshot)
dynamic_cast(m_gizmos[SlaSupports].get())->reslice_SLA_supports(true);
}
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border_w, float border_h) const
+{
+ const unsigned int tex_id = m_background_texture.texture.get_id();
+ const float tex_width = float(m_background_texture.texture.get_width());
+ const float tex_height = float(m_background_texture.texture.get_height());
+ if (tex_id != 0 && tex_width > 0 && tex_height > 0) {
+ const float inv_tex_width = (tex_width != 0.0f) ? 1.0f / tex_width : 0.0f;
+ const float inv_tex_height = (tex_height != 0.0f) ? 1.0f / tex_height : 0.0f;
+
+ const float internal_left = left + border_w;
+ const float internal_right = right - border_w;
+ const float internal_top = top - border_h;
+ const float internal_bottom = bottom + border_h;
+
+ // float left_uv = 0.0f;
+ const float right_uv = 1.0f;
+ const float top_uv = 1.0f;
+ const float bottom_uv = 0.0f;
+
+ const float internal_left_uv = float(m_background_texture.metadata.left) * inv_tex_width;
+ const float internal_right_uv = 1.0f - float(m_background_texture.metadata.right) * inv_tex_width;
+ const float internal_top_uv = 1.0f - float(m_background_texture.metadata.top) * inv_tex_height;
+ const float internal_bottom_uv = float(m_background_texture.metadata.bottom) * inv_tex_height;
+
+ // top-left corner
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_top, top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+
+ // top edge
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_top, top, { { internal_left_uv, internal_top_uv }, { internal_right_uv, internal_top_uv }, { internal_right_uv, top_uv }, { internal_left_uv, top_uv } });
+
+ // top-right corner
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_top, top, { { internal_right_uv, internal_top_uv }, { right_uv, internal_top_uv }, { right_uv, top_uv }, { internal_right_uv, top_uv } });
+
+ // center-left edge
+ GLTexture::render_sub_texture(tex_id, left, internal_left, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+
+ // center
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, internal_bottom, internal_top, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+
+ // center-right edge
+ GLTexture::render_sub_texture(tex_id, internal_right, right, internal_bottom, internal_top, { { internal_right_uv, internal_bottom_uv }, { right_uv, internal_bottom_uv }, { right_uv, internal_top_uv }, { internal_right_uv, internal_top_uv } });
+
+ // bottom-left corner
+ GLTexture::render_sub_texture(tex_id, left, internal_left, bottom, internal_bottom, { { internal_left_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_right_uv, internal_top_uv }, { internal_left_uv, internal_top_uv } });
+
+ // bottom edge
+ GLTexture::render_sub_texture(tex_id, internal_left, internal_right, bottom, internal_bottom, { { internal_left_uv, bottom_uv }, { internal_right_uv, bottom_uv }, { internal_right_uv, internal_bottom_uv }, { internal_left_uv, internal_bottom_uv } });
+
+ // bottom-right corner
+ GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
+ }
+}
+#else
void GLGizmosManager::render_background(float left, float top, float right, float bottom, float border) const
{
const unsigned int tex_id = m_background_texture.texture.get_id();
@@ -717,7 +782,56 @@ void GLGizmosManager::render_background(float left, float top, float right, floa
GLTexture::render_sub_texture(tex_id, internal_right, right, bottom, internal_bottom, { { internal_right_uv, bottom_uv }, { right_uv, bottom_uv }, { right_uv, internal_bottom_uv }, { internal_right_uv, internal_bottom_uv } });
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_type) const
+{
+ const std::vector selectable_idxs = get_selectable_idxs();
+ if (selectable_idxs.empty())
+ return;
+
+ const Size cnv_size = m_parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ if (cnv_w == 0 || cnv_h == 0)
+ return;
+
+ const float inv_cnv_w = 1.0f / cnv_w;
+ const float inv_cnv_h = 1.0f / cnv_h;
+
+ const float top_x = -1.0f;
+ float top_y = get_scaled_total_height() * inv_cnv_h;
+
+ const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w;
+ const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h;
+ const float stride_y = 2.0f * m_layout.scaled_stride_y() * inv_cnv_h;
+
+ for (size_t idx : selectable_idxs) {
+ if (idx == highlighted_type) {
+ const int tex_width = m_arrow_texture.get_width();
+ const int tex_height = m_arrow_texture.get_height();
+ const unsigned int tex_id = m_arrow_texture.get_id();
+
+ const float arrow_size_x = 2.0f * m_layout.scale * float(tex_height) * inv_cnv_w;
+ const float arrow_size_y = 2.0f * m_layout.scale * float(tex_width) * inv_cnv_h;
+
+ const float left_uv = 0.0f;
+ const float right_uv = 1.0f;
+ const float top_uv = 1.0f;
+ const float bottom_uv = 0.0f;
+
+ const float left = top_x + icons_size_x + 6.0f * m_layout.scaled_border() * inv_cnv_w;
+ const float right = left + arrow_size_x * icons_size_y / arrow_size_y;
+
+ GLTexture::render_sub_texture(tex_id, left, right, top_y, top_y + icons_size_y, { { left_uv, bottom_uv }, { left_uv, top_uv }, { right_uv, top_uv }, { right_uv, bottom_uv } });
+ break;
+ }
+ top_y -= stride_y;
+ }
+}
+#else
void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_type) const
{
std::vector selectable_idxs = get_selectable_idxs();
@@ -756,21 +870,95 @@ void GLGizmosManager::render_arrow(const GLCanvas3D& parent, EType highlighted_t
zoomed_top_y -= zoomed_stride_y;
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+void GLGizmosManager::do_render_overlay() const
+{
+ const std::vector selectable_idxs = get_selectable_idxs();
+ if (selectable_idxs.empty())
+ return;
+
+ const Size cnv_size = m_parent.get_canvas_size();
+ const float cnv_w = (float)cnv_size.get_width();
+ const float cnv_h = (float)cnv_size.get_height();
+
+ if (cnv_w == 0 || cnv_h == 0)
+ return;
+
+ const float inv_cnv_w = 1.0f / cnv_w;
+ const float inv_cnv_h = 1.0f / cnv_h;
+
+ const float height = 2.0f * get_scaled_total_height() * inv_cnv_h;
+ const float width = 2.0f * get_scaled_total_width() * inv_cnv_w;
+ const float border_h = 2.0f * m_layout.scaled_border() * inv_cnv_h;
+ const float border_w = 2.0f * m_layout.scaled_border() * inv_cnv_w;
+
+ float top_x = -1.0f;
+ float top_y = 0.5f * height;
+
+ render_background(top_x, top_y, top_x + width, top_y - height, border_w, border_h);
+
+ top_x += border_w;
+ top_y -= border_h;
+
+ const float icons_size_x = 2.0f * m_layout.scaled_icons_size() * inv_cnv_w;
+ const float icons_size_y = 2.0f * m_layout.scaled_icons_size() * inv_cnv_h;
+ const float stride_y = 2.0f * m_layout.scaled_stride_y() * inv_cnv_h;
+
+ const unsigned int icons_texture_id = m_icons_texture.get_id();
+ const int tex_width = m_icons_texture.get_width();
+ const int tex_height = m_icons_texture.get_height();
+
+ if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1)
+ return;
+
+ const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons
+ const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height);
+
+ // tiles in the texture are spaced by 1 pixel
+ const float u_offset = 1.0f / (float)tex_width;
+ const float v_offset = 1.0f / (float)tex_height;
+
+ float current_y = FLT_MAX;
+ for (size_t idx : selectable_idxs) {
+ GLGizmoBase* gizmo = m_gizmos[idx].get();
+ const unsigned int sprite_id = gizmo->get_sprite_id();
+ // higlighted state needs to be decided first so its highlighting in every other state
+ const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable() ? 0 : 3)));
+
+ const float u_left = u_offset + icon_idx * du;
+ const float u_right = u_left + du - u_offset;
+ const float v_top = v_offset + sprite_id * dv;
+ const float v_bottom = v_top + dv - v_offset;
+
+ GLTexture::render_sub_texture(icons_texture_id, top_x, top_x + icons_size_x, top_y - icons_size_y, top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
+ if (idx == m_current || current_y == FLT_MAX) {
+ // The FLT_MAX trick is here so that even non-selectable but activable
+ // gizmos are passed some meaningful value.
+ current_y = 0.5f * cnv_h - 0.5f * top_y * cnv_h;
+ }
+ top_y -= stride_y;
+ }
+
+ if (m_current != Undefined)
+ m_gizmos[m_current]->render_input_window(get_scaled_total_width(), current_y, cnv_h - wxGetApp().plater()->get_view_toolbar().get_height());
+}
+#else
void GLGizmosManager::do_render_overlay() const
{
std::vector selectable_idxs = get_selectable_idxs();
if (selectable_idxs.empty())
return;
- float cnv_w = (float)m_parent.get_canvas_size().get_width();
- float cnv_h = (float)m_parent.get_canvas_size().get_height();
- float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
- float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
+ const float cnv_w = (float)m_parent.get_canvas_size().get_width();
+ const float cnv_h = (float)m_parent.get_canvas_size().get_height();
+ const float zoom = (float)wxGetApp().plater()->get_camera().get_zoom();
+ const float inv_zoom = (float)wxGetApp().plater()->get_camera().get_inv_zoom();
- float height = get_scaled_total_height();
- float width = get_scaled_total_width();
- float zoomed_border = m_layout.scaled_border() * inv_zoom;
+ const float height = get_scaled_total_height();
+ const float width = get_scaled_total_width();
+ const float zoomed_border = m_layout.scaled_border() * inv_zoom;
float zoomed_top_x = (-0.5f * cnv_w) * inv_zoom;
float zoomed_top_y = (0.5f * height) * inv_zoom;
@@ -785,36 +973,35 @@ void GLGizmosManager::do_render_overlay() const
zoomed_top_x += zoomed_border;
zoomed_top_y -= zoomed_border;
- float icons_size = m_layout.scaled_icons_size();
- float zoomed_icons_size = icons_size * inv_zoom;
- float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom;
+ const float icons_size = m_layout.scaled_icons_size();
+ const float zoomed_icons_size = icons_size * inv_zoom;
+ const float zoomed_stride_y = m_layout.scaled_stride_y() * inv_zoom;
- unsigned int icons_texture_id = m_icons_texture.get_id();
- int tex_width = m_icons_texture.get_width();
- int tex_height = m_icons_texture.get_height();
+ const unsigned int icons_texture_id = m_icons_texture.get_id();
+ const int tex_width = m_icons_texture.get_width();
+ const int tex_height = m_icons_texture.get_height();
- if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1))
+ if (icons_texture_id == 0 || tex_width <= 1 || tex_height <= 1)
return;
- float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons
- float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height);
+ const float du = (float)(tex_width - 1) / (6.0f * (float)tex_width); // 6 is the number of possible states if the icons
+ const float dv = (float)(tex_height - 1) / (float)(m_gizmos.size() * tex_height);
// tiles in the texture are spaced by 1 pixel
- float u_offset = 1.0f / (float)tex_width;
- float v_offset = 1.0f / (float)tex_height;
+ const float u_offset = 1.0f / (float)tex_width;
+ const float v_offset = 1.0f / (float)tex_height;
- float current_y = FLT_MAX;
- for (size_t idx : selectable_idxs)
- {
+ float current_y = FLT_MAX;
+ for (size_t idx : selectable_idxs) {
GLGizmoBase* gizmo = m_gizmos[idx].get();
- unsigned int sprite_id = gizmo->get_sprite_id();
+ const unsigned int sprite_id = gizmo->get_sprite_id();
// higlighted state needs to be decided first so its highlighting in every other state
- int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3)));
+ const int icon_idx = (m_highlight.first == idx ? (m_highlight.second ? 4 : 5) : (m_current == idx) ? 2 : ((m_hover == idx) ? 1 : (gizmo->is_activable()? 0 : 3)));
- float v_top = v_offset + sprite_id * dv;
- float u_left = u_offset + icon_idx * du;
- float v_bottom = v_top + dv - v_offset;
- float u_right = u_left + du - u_offset;
+ const float u_left = u_offset + icon_idx * du;
+ const float u_right = u_left + du - u_offset;
+ const float v_top = v_offset + sprite_id * dv;
+ const float v_bottom = v_top + dv - v_offset;
GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
if (idx == m_current || current_y == FLT_MAX) {
@@ -826,10 +1013,11 @@ void GLGizmosManager::do_render_overlay() const
}
if (m_current != Undefined) {
- float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height();
+ const float toolbar_top = cnv_h - wxGetApp().plater()->get_view_toolbar().get_height();
m_gizmos[m_current]->render_input_window(width, current_y, toolbar_top);
}
}
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
float GLGizmosManager::get_scaled_total_height() const
{
@@ -859,14 +1047,12 @@ GLGizmosManager::EType GLGizmosManager::get_gizmo_from_name(const std::string& g
return GLGizmosManager::EType::Undefined;
}
-bool GLGizmosManager::generate_icons_texture() const
+bool GLGizmosManager::generate_icons_texture()
{
std::string path = resources_dir() + "/icons/";
std::vector filenames;
- for (size_t idx=0; idxget_icon_filename();
if (!icon_filename.empty())
filenames.push_back(path + icon_filename);
@@ -907,6 +1093,10 @@ void GLGizmosManager::update_hover_state(const EType &type)
m_tooltip = hovered_gizmo.get_name();
}
+
+
+// Activate given gizmo. Returns true if successful, false in case that current
+// gizmo vetoed its deactivation.
bool GLGizmosManager::activate_gizmo(EType type)
{
assert(!m_gizmos.empty());
diff --git a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
index b8dfdec78..187afd889 100644
--- a/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
+++ b/src/slic3r/GUI/Gizmos/GLGizmosManager.hpp
@@ -34,7 +34,7 @@ public:
Rect() = default;
Rect(float left, float top, float right, float bottom) : m_left(left) , m_top(top) , m_right(right) , m_bottom(bottom) {}
-#if ENABLE_GLBEGIN_GLEND_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
bool operator == (const Rect& other) const {
if (std::abs(m_left - other.m_left) > EPSILON) return false;
if (std::abs(m_top - other.m_top) > EPSILON) return false;
@@ -43,7 +43,7 @@ public:
return true;
}
bool operator != (const Rect& other) const { return !operator==(other); }
-#endif // ENABLE_GLBEGIN_GLEND_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
float get_left() const { return m_left; }
void set_left(float left) { m_left = left; }
@@ -102,10 +102,14 @@ private:
GLCanvas3D& m_parent;
bool m_enabled;
std::vector> m_gizmos;
- mutable GLTexture m_icons_texture;
- mutable bool m_icons_texture_dirty;
+ GLTexture m_icons_texture;
+ bool m_icons_texture_dirty;
BackgroundTexture m_background_texture;
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLTexture m_arrow_texture;
+#else
BackgroundTexture m_arrow_texture;
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
Layout m_layout;
EType m_current;
EType m_hover;
@@ -133,7 +137,11 @@ public:
bool init();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ bool init_arrow(const std::string& filename);
+#else
bool init_arrow(const BackgroundTexture::Metadata& arrow_texture);
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
template
void load(Archive& ar)
@@ -208,7 +216,7 @@ public:
void render_current_gizmo_for_picking_pass() const;
void render_painter_gizmo();
- void render_overlay() const;
+ void render_overlay();
void render_arrow(const GLCanvas3D& parent, EType highlighted_type) const;
@@ -234,14 +242,18 @@ private:
bool alt_down = false,
bool control_down = false);
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ void render_background(float left, float top, float right, float bottom, float border_w, float border_h) const;
+#else
void render_background(float left, float top, float right, float bottom, float border) const;
-
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
+
void do_render_overlay() const;
float get_scaled_total_height() const;
float get_scaled_total_width() const;
- bool generate_icons_texture() const;
+ bool generate_icons_texture();
void update_hover_state(const EType &type);
bool grabber_contains_mouse() const;
diff --git a/src/slic3r/GUI/MeshUtils.cpp b/src/slic3r/GUI/MeshUtils.cpp
index 3787abb2f..e7e9ba2fb 100644
--- a/src/slic3r/GUI/MeshUtils.cpp
+++ b/src/slic3r/GUI/MeshUtils.cpp
@@ -6,10 +6,13 @@
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/Model.hpp"
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/GUI_App.hpp"
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
#include "slic3r/GUI/Camera.hpp"
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+#include "slic3r/GUI/Plater.hpp"
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
#include
@@ -67,25 +70,35 @@ void MeshClipper::set_transformation(const Geometry::Transformation& trafo)
}
}
-
-
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
void MeshClipper::render_cut(const ColorRGBA& color)
#else
void MeshClipper::render_cut()
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
{
if (! m_triangles_valid)
recalculate_triangles();
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
+ if (m_model.vertices_count() == 0 || m_model.indices_count() == 0)
+ return;
+
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
if (curr_shader != nullptr)
curr_shader->stop_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ GLShaderProgram* shader = wxGetApp().get_shader("flat_attr");
+#else
GLShaderProgram* shader = wxGetApp().get_shader("flat");
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
if (shader != nullptr) {
shader->start_using();
+#if ENABLE_GL_SHADERS_ATTRIBUTES
+ const Camera& camera = wxGetApp().plater()->get_camera();
+ shader->set_uniform("view_model_matrix", camera.get_view_matrix());
+ shader->set_uniform("projection_matrix", camera.get_projection_matrix());
+#endif // ENABLE_GL_SHADERS_ATTRIBUTES
m_model.set_color(color);
m_model.render();
shader->stop_using();
@@ -96,7 +109,7 @@ void MeshClipper::render_cut()
#else
if (m_vertex_array.has_VBOs())
m_vertex_array.render();
-#endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#endif // ENABLE_LEGACY_OPENGL_REMOVAL
}
@@ -185,11 +198,11 @@ void MeshClipper::recalculate_triangles()
tr.pretranslate(0.001 * m_plane.get_normal().normalized()); // to avoid z-fighting
-#if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL
+#if ENABLE_LEGACY_OPENGL_REMOVAL
m_model.reset();
GLModel::Geometry init_data;
- init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3, GLModel::Geometry::index_type(m_triangles2d.size()) };
+ init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3 };
init_data.reserve_vertices(m_triangles2d.size());
init_data.reserve_indices(m_triangles2d.size());
@@ -199,10 +212,7 @@ void MeshClipper::recalculate_triangles()
init_data.add_vertex((Vec3f)(tr * Vec3d((*(it + 1)).x(), (*(it + 1)).y(), height_mesh)).cast