diff --git a/__init__.py b/__init__.py index 5a084814d..20c89c4b8 100644 --- a/__init__.py +++ b/__init__.py @@ -12,7 +12,7 @@ from .fast64_internal.oot.props_panel_main import OOT_ObjectProperties from .fast64_internal.utility_anim import utility_anim_register, utility_anim_unregister, ArmatureApplyWithMeshOperator -from .fast64_internal.f3d.f3d_material import mat_register, mat_unregister +from .fast64_internal.f3d.f3d_material import mat_register, mat_unregister, check_or_ask_color_management from .fast64_internal.f3d.f3d_render_engine import render_engine_register, render_engine_unregister from .fast64_internal.f3d.f3d_writer import f3d_writer_register, f3d_writer_unregister from .fast64_internal.f3d.f3d_parser import f3d_parser_register, f3d_parser_unregister @@ -175,6 +175,7 @@ class Fast64Settings_Properties(bpy.types.PropertyGroup): name="Prefer RGBA Over CI", description="When enabled, fast64 will default colored textures's format to RGBA even if they fit CI requirements, with the exception of textures that would not fit into TMEM otherwise", ) + dont_ask_color_management: bpy.props.BoolProperty(name="Don't ask to set color management properties") class Fast64_Properties(bpy.types.PropertyGroup): @@ -323,6 +324,8 @@ def upgrade_scene_props_node(): @bpy.app.handlers.persistent def after_load(_a, _b): + if any(mat.is_f3d for mat in bpy.data.materials): + check_or_ask_color_management(bpy.context) upgrade_changed_props() upgrade_scene_props_node() resync_scene_props() diff --git a/fast64_internal/f3d/f3d_material.py b/fast64_internal/f3d/f3d_material.py index 2563aaa85..527533229 100644 --- a/fast64_internal/f3d/f3d_material.py +++ b/fast64_internal/f3d/f3d_material.py @@ -3,6 +3,7 @@ from bpy.types import ( Attribute, Context, + Event, Image, Light, Material, @@ -1693,7 +1694,7 @@ def input_update_callback(self: Material, context: Context): def update_node_values_of_material(material: Material, context): - nodes = material.node_tree.nodes + check_or_ask_color_management(context) update_blend_method(material, context) if not has_f3d_nodes(material): @@ -1705,6 +1706,8 @@ def update_node_values_of_material(material: Material, context): set_output_node_groups(material) + nodes = material.node_tree.nodes + if f3dMat.rdp_settings.g_tex_gen: if f3dMat.rdp_settings.g_tex_gen_linear: nodes["UV"].node_tree = bpy.data.node_groups["UV_EnvMap_Linear"] @@ -2179,7 +2182,6 @@ def has_f3d_nodes(material: Material): @persistent def load_handler(dummy): logger.info("Checking for base F3D material library.") - for lib in bpy.data.libraries: lib_path = bpy.path.abspath(lib.filepath) @@ -2440,6 +2442,76 @@ def reloadDefaultF3DPresets(): update_preset_manual_v4(material, presetNameToFilename[material.f3d_mat.presetName]) +def check_or_ask_color_management(context: Context): + scene = context.scene + fast64_props: "Fast64_Properties" = scene.fast64 + fast64settings_props: "Fast64Settings_Properties" = fast64_props.settings + view_settings = scene.view_settings + # Check if color management settings are correct + if not fast64settings_props.dont_ask_color_management and ( + scene.display_settings.display_device != "sRGB" + or view_settings.view_transform != "Standard" + or view_settings.look != "None" + or view_settings.exposure != 0.0 + or view_settings.gamma != 1.0 + ): + bpy.ops.dialog.fast64_update_color_management("INVOKE_DEFAULT") + + +class UpdateColorManagementPopup(Operator): + bl_label = "Update Color Management" + bl_idname = "dialog.fast64_update_color_management" + bl_description = "Update color management settings to help material preview accuracy" + bl_options = {"UNDO"} + + already_invoked = False # HACK: used to prevent multiple dialogs from popping up + + def invoke(self, context: Context, event: Event): + if UpdateColorManagementPopup.already_invoked: + return {"FINISHED"} + UpdateColorManagementPopup.already_invoked = True + return context.window_manager.invoke_props_dialog(self, width=400) + + def draw(self, context: Context): + col = self.layout.column() + multilineLabel( + col, + ( + ( + f'The color management settings for the current scene "{context.scene.name}"\n' + # use is_library_indirect to not count the scene from f3d_material_library.blend and other "external" scenes + if len([_s for _s in bpy.data.scenes if not _s.is_library_indirect]) >= 2 + else "The color management settings\n" + ) + + "will cause inaccurate preview compared to N64.\n" + + "Would you like to update it?" + ), + icon="INFO", + ) + fast64_props: "Fast64_Properties" = context.scene.fast64 + fast64settings_props: "Fast64Settings_Properties" = fast64_props.settings + col.prop(fast64settings_props, "dont_ask_color_management", text="Don't ask again") + + def cancel(self, context: Context): + UpdateColorManagementPopup.already_invoked = False + + def execute(self, context): + try: + scene = context.scene + scene.display_settings.display_device = "sRGB" + scene.view_settings.view_transform = "Standard" + scene.view_settings.look = "None" + scene.view_settings.exposure = 0.0 + scene.view_settings.gamma = 1.0 + self.report({"INFO"}, "Updated color management settings.") + return {"FINISHED"} + except Exception as exc: + raisePluginError(self, exc) + return {"CANCELLED"} + finally: + UpdateColorManagementPopup.already_invoked = False + + class CreateFast3DMaterial(Operator): bl_idname = "object.create_f3d_mat" bl_label = "Create Fast3D Material" @@ -4404,6 +4476,7 @@ def draw_f3d_render_settings(self, context): mat_classes = ( + UpdateColorManagementPopup, UnlinkF3DImage0, UnlinkF3DImage1, DrawLayerProperty,