From ad6d2add1bfe6a0366052610b94c0ac902b1f305 Mon Sep 17 00:00:00 2001 From: ChaoticByte Date: Sat, 21 Dec 2024 18:25:11 +0100 Subject: [PATCH] Cleaned up and refactored some code --- project.godot | 3 +- src/Camera.gd | 34 ++++++++-------- src/Editor.gd | 43 ++++++-------------- src/Filesystem.gd | 59 +++++++++++++++++++++++++++ src/Globals.gd | 6 --- src/ImageViewport.gd | 77 +++++++++++------------------------- src/ShaderDirectiveParser.gd | 23 +++++++++++ 7 files changed, 135 insertions(+), 110 deletions(-) create mode 100644 src/Filesystem.gd delete mode 100644 src/Globals.gd create mode 100644 src/ShaderDirectiveParser.gd diff --git a/project.godot b/project.godot index ddea23b..6c19409 100644 --- a/project.godot +++ b/project.godot @@ -19,7 +19,8 @@ config/icon="res://icon.png" [autoload] -Globals="*res://src/Globals.gd" +Filesystem="*res://src/Filesystem.gd" +ShaderDirectiveParser="*res://src/ShaderDirectiveParser.gd" [display] diff --git a/src/Camera.gd b/src/Camera.gd index ab5b939..716cd9b 100644 --- a/src/Camera.gd +++ b/src/Camera.gd @@ -11,37 +11,37 @@ func _input(event): elif event.is_action_pressed("zoom_in"): zoom_in() if event.is_action_pressed("drag"): - drag = true + self.drag = true elif event.is_action_released("drag"): - drag = false - if drag && event is InputEventMouseMotion: - global_position -= event.relative / zoom + self.drag = false + if self.drag && event is InputEventMouseMotion: + self.global_position -= event.relative / self.zoom func fit_image(): - if image_viewport.image_original_tex != null: - var image_size = image_viewport.image_original_tex.get_size() + if Filesystem.original_image != null: + var image_size = Filesystem.original_image.get_size() var viewport_size = get_viewport_rect().size var zoomf = viewport_size.x / image_size.x / 1.1 if zoomf * image_size.y > viewport_size.y: zoomf = viewport_size.y / image_size.y / 1.1 - zoom = Vector2(zoomf, zoomf) - global_position = Vector2(0, 0) + self.zoom = Vector2(zoomf, zoomf) + self.global_position = Vector2(0, 0) -func update_viewport_display(): - image_viewport_display.update_zoom_texture_filter(zoom) - image_viewport_display.material.set_shader_parameter("zoom_level", zoom) +func update_vd_zoomlevel(): + image_viewport_display.update_zoom_texture_filter(self.zoom) + image_viewport_display.material.set_shader_parameter("zoom_level", self.zoom) func zoom_in(): var old_mouse_pos = get_global_mouse_position() - zoom *= 1.2 - global_position += old_mouse_pos - get_global_mouse_position() - update_viewport_display() + self.zoom *= 1.2 + self.global_position += old_mouse_pos - get_global_mouse_position() + update_vd_zoomlevel() func zoom_out(): var old_mouse_pos = get_global_mouse_position() - zoom *= 1/1.2 - global_position += old_mouse_pos - get_global_mouse_position() - update_viewport_display() + self.zoom *= 1/1.2 + self.global_position += old_mouse_pos - get_global_mouse_position() + update_vd_zoomlevel() func _on_fit_image_button_pressed(): fit_image() diff --git a/src/Editor.gd b/src/Editor.gd index f5f21d2..24d0e62 100644 --- a/src/Editor.gd +++ b/src/Editor.gd @@ -171,7 +171,7 @@ func _on_code_edit_code_completion_requested(): func _ready(): code_editor.code_completion_enabled = true code_editor.syntax_highlighter = ShaderSyntaxHighlighter.new() - update() + self.update() func _input(event): if event.is_action_pressed("apply_shader"): @@ -181,55 +181,36 @@ func _input(event): _on_save_shader_button_pressed() func update(): - code_editor.text = Globals.shader.code + code_editor.text = Filesystem.shader.code func _on_open_shader_button_pressed(): open_shader_dialog.show() func _on_save_shader_button_pressed(): - if Globals.last_shader_savepath == "": - save_shader_dialog.current_file = "shader.gdshader" + if Filesystem.last_shader_savepath == "": + save_shader_dialog.current_file = "filter.gdshader" else: - save_shader_dialog.current_path = Globals.last_shader_savepath + save_shader_dialog.current_path = Filesystem.last_shader_savepath save_shader_dialog.show() func _on_open_shader_dialog_file_selected(path: String): - print("Load ", path) - var file = FileAccess.open(path, FileAccess.READ) - var shader_code = file.get_as_text() - var shader = Shader.new() - shader.code = shader_code - Globals.shader = shader - if "/" in path: # update current working directory - Globals.cwd = path.substr(0, path.rfind("/")) + Filesystem.load_shader(path) image_viewport.update() - update() - Globals.last_shader_savepath = path + self.update() func _on_save_shader_dialog_file_selected(path): - print("Save ", path) - var file = FileAccess.open(path, FileAccess.WRITE) - var content = code_editor.text - file.store_string(content) - if "/" in path: # update current working directory - Globals.cwd = path.substr(0, path.rfind("/")) - Globals.last_shader_savepath = path + Filesystem.save_shader(path, code_editor.text) func _on_apply_shader_button_pressed(): var shader = Shader.new() shader.code = code_editor.text - Globals.shader = shader + Filesystem.shader = shader image_viewport.update() func _on_save_image_button_pressed(): - if image_viewport.get_result() != null: - ui_control_filesave.current_path = Globals.last_image_savepath + if Filesystem.result != null: + ui_control_filesave.current_path = Filesystem.last_image_savepath ui_control_filesave.show() func _on_save_image_dialog_file_selected(path): - print("Export ", path) - var err = image_viewport.get_result().save_png(path) - if err != OK: - print("An error occured!") - else: - Globals.last_image_savepath = path + Filesystem.save_result(path) diff --git a/src/Filesystem.gd b/src/Filesystem.gd new file mode 100644 index 0000000..9530b39 --- /dev/null +++ b/src/Filesystem.gd @@ -0,0 +1,59 @@ +extends Node + +@onready var shader: Shader = load("res://src/shader/template.gdshader") +var original_image: ImageTexture +var result: Image + +var cwd = "." +var last_image_savepath = "" +var last_shader_savepath = "" +var last_original_image_path = "" + +func get_absolute_path(p: String) -> String: + # this only works on Linux! + if !p.begins_with("/"): + return self.cwd + "/" + p.lstrip("./") + return p + +func load_original_image(path: String): + print("Load ", path) + var img = Image.new() + var err = img.load(path) + if err == OK: + original_image = ImageTexture.create_from_image(img) + if path != self.last_original_image_path: + self.last_original_image_path = path + if self.last_image_savepath == "": + self.last_image_savepath = path + else: + print("An error occured!") + +func load_image(path: String) -> ImageTexture: + print("Load ", path) + return ImageTexture.create_from_image(Image.load_from_file(path)) + +func save_result(path: String): + print("Export ", path) + var err = self.result.save_png(path) + if err != OK: + print("An error occured!") + else: + self.last_image_savepath = path + +func load_shader(path: String): + print("Load ", path) + var file = FileAccess.open(path, FileAccess.READ) + var shader_code = file.get_as_text() + self.shader = Shader.new() + shader.code = shader_code + if "/" in path: # update current working directory + self.cwd = path.substr(0, path.rfind("/")) + self.last_shader_savepath = path + +func save_shader(path: String, content: String): + print("Save ", path) + var file = FileAccess.open(path, FileAccess.WRITE) + file.store_string(content) + if "/" in path: # update current working directory + self.cwd = path.substr(0, path.rfind("/")) + self.last_shader_savepath = path diff --git a/src/Globals.gd b/src/Globals.gd deleted file mode 100644 index 9372495..0000000 --- a/src/Globals.gd +++ /dev/null @@ -1,6 +0,0 @@ -extends Node - -@onready var shader: Shader = load("res://src/shader/template.gdshader") -var cwd = "." -var last_image_savepath = "" -var last_shader_savepath = "" diff --git a/src/ImageViewport.gd b/src/ImageViewport.gd index fc05b5c..5f95fe6 100644 --- a/src/ImageViewport.gd +++ b/src/ImageViewport.gd @@ -4,70 +4,37 @@ extends SubViewport @onready var image_sprite = %ImageSprite @onready var image_viewport_display = %ImageViewportDisplay -var image_original_tex: ImageTexture -var image_result: Image -var load_regex: RegEx -var load_additional_regex: RegEx -var last_tex_path = "" - -func _ready(): - load_regex = RegEx.new() - load_additional_regex = RegEx.new() - load_regex.compile(r'\/\/!load\s(.*)') - load_additional_regex.compile(r'\/\/!load\+\s(\w*)\s(.*)') - -func load_texture(path): - print("Load ", path) - var img = Image.new() - var err = img.load(path) - if err == OK: - image_original_tex = ImageTexture.create_from_image(img) - image_sprite.texture = image_original_tex - image_sprite.offset = image_original_tex.get_size() / 2 - size = image_original_tex.get_size() - else: - print("An error occured!") - -func get_absolute_path(p: String) -> String: - if !p.begins_with("/"): - return Globals.cwd + "/" + p.lstrip("./") - return p - func update(): - # load images from //!load directive -> TEXTURE - var regex_match = load_regex.search(Globals.shader.code) - if regex_match == null: # Error! - printerr("Didn't find any load directives!") + var fit_image = false + # load image from //!load directive -> TEXTURE + var m = ShaderDirectiveParser.parse_load_directive(Filesystem.shader) + if len(m) < 1: + return # AAAAAAAa + var original_image_path = Filesystem.get_absolute_path(m[1]) + if original_image_path != Filesystem.last_original_image_path: + fit_image = true + Filesystem.load_original_image(original_image_path) + if Filesystem.original_image == null: return - var tex_path = get_absolute_path(regex_match.strings[1]) - load_texture(tex_path) # load every time - if tex_path != last_tex_path: - camera.fit_image() - last_tex_path = tex_path - if Globals.last_image_savepath == "": - Globals.last_image_savepath = tex_path - image_sprite.texture = image_original_tex + image_sprite.texture = Filesystem.original_image + image_sprite.offset = Filesystem.original_image.get_size() / 2 + self.size = Filesystem.original_image.get_size() var mat = ShaderMaterial.new() - mat.shader = Globals.shader + mat.shader = Filesystem.shader # load images from //!load+ directives and apply them to # the material as shader parameters - for m in load_additional_regex.search_all(Globals.shader.code): - # this only works for Linux! - var img_path = get_absolute_path(m.strings[2]) - # - print("Load ", img_path) - var u_image = Image.load_from_file(img_path) + for n in ShaderDirectiveParser.parse_load_additional_directive(Filesystem.shader): mat.set_shader_parameter( - m.strings[1], # uniform param name - ImageTexture.create_from_image(u_image)) + n[1], # uniform param name + Filesystem.load_image(Filesystem.get_absolute_path(n[2])) + ) # assign material image_sprite.material = mat # Get viewport texture await RenderingServer.frame_post_draw # for good measure - image_result = get_texture().get_image() + Filesystem.result = get_texture().get_image() image_sprite.material = null - image_sprite.texture = ImageTexture.create_from_image(image_result) + image_sprite.texture = ImageTexture.create_from_image(Filesystem.result) + if fit_image: + camera.fit_image() image_viewport_display.show() - -func get_result(): - return image_result diff --git a/src/ShaderDirectiveParser.gd b/src/ShaderDirectiveParser.gd new file mode 100644 index 0000000..936eaa7 --- /dev/null +++ b/src/ShaderDirectiveParser.gd @@ -0,0 +1,23 @@ +extends Node + +var _load_regex: RegEx +var _load_additional_regex: RegEx + +func _ready(): + self._load_regex = RegEx.new() + self._load_additional_regex = RegEx.new() + self._load_regex.compile(r'\/\/!load\s(.*)') + self._load_additional_regex.compile(r'\/\/!load\+\s(\w*)\s(.*)') + +func parse_load_directive(shader: Shader) -> PackedStringArray: + var regex_match = self._load_regex.search(Filesystem.shader.code) + if regex_match == null: # Error! + printerr("Didn't find any load directives!") + return [] + return regex_match.strings + +func parse_load_additional_directive(shader: Shader) -> Array[PackedStringArray]: + var results : Array[PackedStringArray] = [] + for m in self._load_additional_regex.search_all(shader.code): + results.append(m.strings) + return results