diff --git a/README.md b/README.md
index cbe9a36..e2e92db 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
GlitchApp
+Fragmented

@@ -9,30 +9,39 @@
- Linux
-You can find the latest releases [here](https://github.com/ChaoticByte/GlitchApp/releases/latest).
+You can find the latest releases [here](https://github.com/ChaoticByte/Fragmented/releases/latest).
## Usage
-The application includes presets. You can use them as a starting-point to write your own filters.
-Just load an image, apply a preset, edit the code and hit `F5` to see the changes.
+The repo includes examples. You can use them as a starting-point to write your own filters.
+Just load an image using `//!load`, edit the shader code and hit `F5` to see the changes.
-### Load additional images using the `//!load` directive
+### Load TEXTURE using the `//!load` directive
+
+```glsl
+//!load
+```
+
+The image file will be read and available as the `TEXTURE` variable.
+
+#### Load additional images
```glsl
//!load
uniform sampler2D ;
```
-With this you can load additional images into your shader.
-Have a look at the `Mix` preset:
+Have a look at the `mix.gdshader` example:
```glsl
shader_type canvas_item;
-//!load img2 ./icon.png
+//!load ./swamp.jpg
+
+//!load+ img2 ./overlay.jpg
uniform sampler2D img2: repeat_enable, filter_nearest;
void fragment() {
- COLOR = mix(COLOR, texture(img2, UV), .5);
+ COLOR = mix(COLOR, texture(img2, UV), .2);
}
```
diff --git a/examples/CREDITS.md b/examples/CREDITS.md
new file mode 100644
index 0000000..99df0e2
--- /dev/null
+++ b/examples/CREDITS.md
@@ -0,0 +1,5 @@
+
+# Example Images
+
+- swamp.jpg by [clfr21](https://pixabay.com/de/users/clfr21-6530007/)
+- overlay.jpg by [Humusak](https://pixabay.com/de/users/humusak-137455/)
diff --git a/src/presets/shaders/channel_offset.gdshader b/examples/channel_offset.gdshader
similarity index 94%
rename from src/presets/shaders/channel_offset.gdshader
rename to examples/channel_offset.gdshader
index e3ac188..73915ea 100644
--- a/src/presets/shaders/channel_offset.gdshader
+++ b/examples/channel_offset.gdshader
@@ -1,5 +1,7 @@
shader_type canvas_item;
+//!load ./swamp.jpg
+
const vec2 offset_r = vec2(-0.002, -0.002);
const vec2 offset_g = vec2(0., 0.);
const vec2 offset_b = vec2(0.002, 0.002);
diff --git a/src/presets/shaders/greyscale.gdshader b/examples/greyscale.gdshader
similarity index 71%
rename from src/presets/shaders/greyscale.gdshader
rename to examples/greyscale.gdshader
index cd70a78..921c591 100644
--- a/src/presets/shaders/greyscale.gdshader
+++ b/examples/greyscale.gdshader
@@ -1,10 +1,10 @@
shader_type canvas_item;
+//!load ./swamp.jpg
+
void fragment() {
- vec4 tex = texture(TEXTURE , UV);
float b = (COLOR.r + COLOR.g + COLOR.b) / 3.0;
COLOR.r = b;
COLOR.g = b;
COLOR.b = b;
- COLOR.a = tex.a;
}
diff --git a/src/presets/shaders/lowpass.gdshader b/examples/lowpass.gdshader
similarity index 92%
rename from src/presets/shaders/lowpass.gdshader
rename to examples/lowpass.gdshader
index 9dc44f7..d2d82c5 100644
--- a/src/presets/shaders/lowpass.gdshader
+++ b/examples/lowpass.gdshader
@@ -1,5 +1,7 @@
shader_type canvas_item;
+//!load ./swamp.jpg
+
// Settings
const float threshold = 0.5;
//
diff --git a/src/presets/shaders/mix.gdshader b/examples/mix.gdshader
similarity index 52%
rename from src/presets/shaders/mix.gdshader
rename to examples/mix.gdshader
index 53ed562..a043856 100644
--- a/src/presets/shaders/mix.gdshader
+++ b/examples/mix.gdshader
@@ -1,8 +1,10 @@
shader_type canvas_item;
-//!load img2 ./icon.png
+//!load ./swamp.jpg
+
+//!load+ img2 ./overlay.jpg
uniform sampler2D img2: repeat_enable, filter_nearest;
void fragment() {
- COLOR = mix(COLOR, texture(img2, UV), .5);
+ COLOR = mix(COLOR, texture(img2, UV), .2);
}
diff --git a/examples/overlay.jpg b/examples/overlay.jpg
new file mode 100644
index 0000000..b305379
Binary files /dev/null and b/examples/overlay.jpg differ
diff --git a/examples/overlay.jpg.import b/examples/overlay.jpg.import
new file mode 100644
index 0000000..7d189f0
--- /dev/null
+++ b/examples/overlay.jpg.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://8101nnc8cx4o"
+path="res://.godot/imported/overlay.jpg-b6d13e0def59877969c9eda02fa4244e.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://examples/overlay.jpg"
+dest_files=["res://.godot/imported/overlay.jpg-b6d13e0def59877969c9eda02fa4244e.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/src/presets/shaders/rgb_uv_distort.gdshader b/examples/rgb_uv_distort.gdshader
similarity index 91%
rename from src/presets/shaders/rgb_uv_distort.gdshader
rename to examples/rgb_uv_distort.gdshader
index c07466b..1b65816 100644
--- a/src/presets/shaders/rgb_uv_distort.gdshader
+++ b/examples/rgb_uv_distort.gdshader
@@ -1,5 +1,7 @@
shader_type canvas_item;
+//!load ./swamp.jpg
+
const float strength = 0.1;
void fragment() {
diff --git a/examples/swamp.jpg b/examples/swamp.jpg
new file mode 100644
index 0000000..d7bdf3c
Binary files /dev/null and b/examples/swamp.jpg differ
diff --git a/examples/swamp.jpg.import b/examples/swamp.jpg.import
new file mode 100644
index 0000000..3cc2a0b
--- /dev/null
+++ b/examples/swamp.jpg.import
@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://ckjb0agn5btv7"
+path="res://.godot/imported/swamp.jpg-8e3eac7e7aacce65638e712310cdb35c.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://examples/swamp.jpg"
+dest_files=["res://.godot/imported/swamp.jpg-8e3eac7e7aacce65638e712310cdb35c.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
diff --git a/export_presets.cfg b/export_presets.cfg
index df6f7ca..d1be5f0 100644
--- a/export_presets.cfg
+++ b/export_presets.cfg
@@ -8,7 +8,7 @@ custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
-export_path="dist/GlitchApp.x86_64"
+export_path="dist/Fragmented.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
diff --git a/project.godot b/project.godot
index df98a4f..cee024d 100644
--- a/project.godot
+++ b/project.godot
@@ -10,16 +10,15 @@ config_version=5
[application]
-config/name="Glitch"
-config/version="v4.0"
+config/name="Fragmented"
+config/version="v5.0"
run/main_scene="res://scenes/main.tscn"
-config/features=PackedStringArray("4.2", "Mobile")
+config/features=PackedStringArray("4.3", "Mobile")
run/low_processor_mode=true
config/icon="res://icon.png"
[autoload]
-ShaderPresets="*res://src/presets/Presets.gd"
Globals="*res://src/Globals.gd"
[display]
@@ -28,6 +27,7 @@ window/size/viewport_width=1280
window/size/viewport_height=720
window/size/mode=2
window/energy_saving/keep_screen_on=false
+window/vsync/vsync_mode=0
[editor_plugins]
@@ -38,15 +38,15 @@ enabled=PackedStringArray()
zoom_out={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(244, 15),"global_position":Vector2(248, 56),"factor":1.0,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null)
-, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":45,"physical_keycode":0,"key_label":0,"unicode":45,"echo":false,"script":null)
-, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194435,"key_label":0,"unicode":45,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":45,"physical_keycode":0,"key_label":0,"unicode":45,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194435,"key_label":0,"unicode":45,"location":0,"echo":false,"script":null)
]
}
zoom_in={
"deadzone": 0.5,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(270, 19),"global_position":Vector2(274, 60),"factor":1.0,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null)
-, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":43,"physical_keycode":0,"key_label":0,"unicode":43,"echo":false,"script":null)
-, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194437,"key_label":0,"unicode":43,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":43,"physical_keycode":0,"key_label":0,"unicode":43,"location":0,"echo":false,"script":null)
+, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194437,"key_label":0,"unicode":43,"location":0,"echo":false,"script":null)
]
}
drag={
@@ -56,12 +56,12 @@ drag={
}
apply_shader={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194336,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194336,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
save_shader={
"deadzone": 0.5,
-"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"echo":false,"script":null)
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
@@ -70,4 +70,5 @@ save_shader={
renderer/rendering_method="mobile"
textures/vram_compression/import_etc2_astc=true
textures/lossless_compression/force_png=true
+shader_compiler/shader_cache/enabled=false
environment/defaults/default_clear_color=Color(0, 0, 0, 1)
diff --git a/scenes/main.tscn b/scenes/main.tscn
index 2ba507d..6792ecb 100644
--- a/scenes/main.tscn
+++ b/scenes/main.tscn
@@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://src/Main.gd" id="1_2625y"]
[ext_resource type="Script" path="res://src/ImageViewport.gd" id="2_hvo65"]
-[ext_resource type="Script" path="res://src/ImageViewportDisplays.gd" id="3_n4itb"]
+[ext_resource type="Script" path="res://src/ImageViewportDisplay.gd" id="3_n4itb"]
[ext_resource type="Shader" path="res://src/ui_background.gdshader" id="4_ty3qx"]
[ext_resource type="Script" path="res://src/UIAppVersion.gd" id="5_o1ggv"]
[ext_resource type="Script" path="res://src/Editor.gd" id="7_g8bap"]
@@ -18,6 +18,7 @@ shader = ExtResource("4_ty3qx")
script = ExtResource("1_2625y")
[node name="ImageViewport" type="SubViewport" parent="."]
+unique_name_in_owner = true
disable_3d = true
transparent_bg = true
canvas_item_default_texture_filter = 0
@@ -25,8 +26,10 @@ render_target_update_mode = 4
script = ExtResource("2_hvo65")
[node name="ImageSprite" type="Sprite2D" parent="ImageViewport"]
+unique_name_in_owner = true
[node name="ImageViewportDisplay" type="Sprite2D" parent="."]
+unique_name_in_owner = true
texture = SubResource("ViewportTexture_lct1c")
script = ExtResource("3_n4itb")
@@ -42,6 +45,7 @@ grow_vertical = 2
focus_mode = 2
[node name="UserInterfaceContainer" type="Control" parent="UI_Layer"]
+unique_name_in_owner = true
layout_mode = 3
anchor_right = 0.225
anchor_bottom = 1.0
@@ -63,87 +67,32 @@ color = Color(1, 1, 1, 0)
[node name="AppName" type="Label" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 0
offset_left = 24.0
-offset_top = 24.0
+offset_top = 16.0
offset_right = 208.0
-offset_bottom = 56.0
+offset_bottom = 48.0
theme_override_font_sizes/font_size = 20
-text = "GlitchApp
-"
+text = "Fragmented"
vertical_alignment = 2
[node name="AppVersion" type="Label" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 0
-offset_left = 128.0
-offset_top = 24.0
+offset_left = 152.0
+offset_top = 17.0
offset_right = 208.0
-offset_bottom = 56.0
+offset_bottom = 47.0
theme_override_font_sizes/font_size = 14
text = "v0
"
vertical_alignment = 2
script = ExtResource("5_o1ggv")
-[node name="OpenImageDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer"]
-title = "Load Image"
-size = Vector2i(521, 159)
-ok_button_text = "Open"
-mode_overrides_title = false
-file_mode = 0
-access = 2
-use_native_dialog = true
-
-[node name="SaveImageDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer"]
-title = "Export Image"
-size = Vector2i(661, 159)
-ok_button_text = "Save"
-mode_overrides_title = false
-access = 2
-filters = PackedStringArray("*.png")
-use_native_dialog = true
-
-[node name="OpenImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
-layout_mode = 1
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -360.0
-offset_top = 24.0
-offset_right = -248.0
-offset_bottom = 56.0
-grow_horizontal = 0
-text = "Load Image"
-
-[node name="SaveImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
-layout_mode = 1
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -240.0
-offset_top = 23.0
-offset_right = -120.0
-offset_bottom = 55.0
-grow_horizontal = 0
-text = "Export Image"
-
-[node name="FitImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
-layout_mode = 1
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -112.0
-offset_top = 24.0
-offset_right = -24.0
-offset_bottom = 56.0
-grow_horizontal = 0
-text = "Fit Image"
-
[node name="Editor" type="Control" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = 24.0
-offset_top = 80.0
+offset_top = 64.0
offset_right = -24.0
offset_bottom = -24.0
grow_horizontal = 2
@@ -151,8 +100,9 @@ grow_vertical = 2
script = ExtResource("7_g8bap")
[node name="OpenShaderDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer/Editor"]
+unique_name_in_owner = true
title = "Load Shader"
-size = Vector2i(521, 159)
+size = Vector2i(521, 175)
ok_button_text = "Open"
mode_overrides_title = false
file_mode = 0
@@ -161,28 +111,27 @@ filters = PackedStringArray("*.gdshader")
use_native_dialog = true
[node name="SaveShaderDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer/Editor"]
+unique_name_in_owner = true
title = "Save Shader"
-size = Vector2i(661, 159)
+size = Vector2i(661, 175)
ok_button_text = "Save"
mode_overrides_title = false
access = 2
filters = PackedStringArray("*.gdshader")
use_native_dialog = true
-[node name="Label" type="Label" parent="UI_Layer/UserInterfaceContainer/Editor"]
-layout_mode = 0
-offset_right = 104.0
-offset_bottom = 32.0
-text = "Load Preset: "
-vertical_alignment = 1
-
-[node name="PresetOptions" type="OptionButton" parent="UI_Layer/UserInterfaceContainer/Editor"]
-layout_mode = 0
-offset_left = 104.0
-offset_right = 240.0
-offset_bottom = 32.0
+[node name="SaveImageDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer/Editor"]
+unique_name_in_owner = true
+title = "Export Image"
+size = Vector2i(661, 175)
+ok_button_text = "Save"
+mode_overrides_title = false
+access = 2
+filters = PackedStringArray("*.png")
+use_native_dialog = true
[node name="CodeEdit" type="CodeEdit" parent="UI_Layer/UserInterfaceContainer/Editor"]
+unique_name_in_owner = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
@@ -208,48 +157,55 @@ auto_brace_completion_highlight_matching = true
[node name="OpenShaderButton" type="Button" parent="UI_Layer/UserInterfaceContainer/Editor"]
layout_mode = 1
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -216.0
-offset_right = -160.0
+offset_right = 56.0
offset_bottom = 32.0
-grow_horizontal = 0
text = "Open"
[node name="SaveShaderButton" type="Button" parent="UI_Layer/UserInterfaceContainer/Editor"]
layout_mode = 1
-anchors_preset = 1
-anchor_left = 1.0
-anchor_right = 1.0
-offset_left = -152.0
-offset_right = -96.0
+offset_left = 64.0
+offset_right = 120.0
offset_bottom = 32.0
-grow_horizontal = 0
text = "Save"
[node name="ApplyShaderButton" type="Button" parent="UI_Layer/UserInterfaceContainer/Editor"]
layout_mode = 1
+offset_left = 128.0
+offset_right = 216.0
+offset_bottom = 32.0
+text = "Apply (F5)"
+
+[node name="SaveImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer/Editor"]
+layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
-offset_left = -88.0
+offset_left = -120.0
offset_bottom = 32.0
grow_horizontal = 0
-text = "Apply (F5)"
+text = "Export Image"
+
+[node name="FitImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer/Editor"]
+layout_mode = 1
+anchors_preset = 1
+anchor_left = 1.0
+anchor_right = 1.0
+offset_left = -216.0
+offset_right = -128.0
+offset_bottom = 32.0
+grow_horizontal = 0
+text = "Fit Image"
[node name="Camera" type="Camera2D" parent="."]
+unique_name_in_owner = true
script = ExtResource("8_mls06")
-[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/OpenImageDialog" to="." method="_on_open_image_dialog_file_selected"]
-[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/SaveImageDialog" to="." method="_on_save_image_dialog_file_selected"]
-[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/OpenImageButton" to="." method="_on_open_image_button_pressed"]
-[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/SaveImageButton" to="." method="_on_save_image_button_pressed"]
-[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/FitImageButton" to="Camera" method="_on_fit_image_button_pressed"]
[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/Editor/OpenShaderDialog" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_open_shader_dialog_file_selected"]
[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/Editor/SaveShaderDialog" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_save_shader_dialog_file_selected"]
-[connection signal="item_selected" from="UI_Layer/UserInterfaceContainer/Editor/PresetOptions" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_preset_options_item_selected"]
+[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/Editor/SaveImageDialog" to="." method="_on_save_image_dialog_file_selected"]
[connection signal="code_completion_requested" from="UI_Layer/UserInterfaceContainer/Editor/CodeEdit" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_code_edit_code_completion_requested"]
[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/Editor/OpenShaderButton" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_open_shader_button_pressed"]
[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/Editor/SaveShaderButton" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_save_shader_button_pressed"]
[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/Editor/ApplyShaderButton" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_apply_shader_button_pressed"]
+[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/Editor/SaveImageButton" to="." method="_on_save_image_button_pressed"]
+[connection signal="pressed" from="UI_Layer/UserInterfaceContainer/Editor/FitImageButton" to="Camera" method="_on_fit_image_button_pressed"]
diff --git a/screenshot.png b/screenshot.png
index 5595ae5..551bf4d 100644
Binary files a/screenshot.png and b/screenshot.png differ
diff --git a/src/Camera.gd b/src/Camera.gd
index 231add8..1bc16f4 100644
--- a/src/Camera.gd
+++ b/src/Camera.gd
@@ -2,8 +2,9 @@ extends Camera2D
var drag = false
-@onready var user_interface_container = get_parent().get_node("UI_Layer/UserInterfaceContainer")
-@onready var image_viewport = get_parent().get_node("ImageViewport")
+@onready var user_interface_container = %UserInterfaceContainer
+@onready var image_viewport = %ImageViewport
+@onready var image_viewport_display = %ImageViewportDisplay
func _input(event):
if event.is_action_pressed("zoom_out") && !Globals.camera_freeze:
@@ -32,11 +33,13 @@ func zoom_in():
var old_mouse_pos = get_global_mouse_position()
zoom *= 1.2
global_position += old_mouse_pos - get_global_mouse_position()
+ image_viewport_display.update_zoom_texture_filter(zoom)
func zoom_out():
var old_mouse_pos = get_global_mouse_position()
zoom *= 1/1.2
global_position += old_mouse_pos - get_global_mouse_position()
+ image_viewport_display.update_zoom_texture_filter(zoom)
func _on_fit_image_button_pressed():
fit_image()
diff --git a/src/Editor.gd b/src/Editor.gd
index a22d5c8..ae8ed61 100644
--- a/src/Editor.gd
+++ b/src/Editor.gd
@@ -1,11 +1,8 @@
extends Control
-@onready var preset_options = $PresetOptions
-@onready var code_editor = $CodeEdit
-@onready var open_shader_dialog = $OpenShaderDialog
-@onready var save_shader_dialog = $SaveShaderDialog
-var selected_preset_name = ShaderPresets.default_preset
-var last_save_filepath = ""
+@onready var code_editor = %CodeEdit
+@onready var open_shader_dialog = %OpenShaderDialog
+@onready var save_shader_dialog = %SaveShaderDialog
# # # # # # # # # # #
# GDShader keywords #
@@ -189,35 +186,17 @@ func _input(event):
accept_event() # Event is now handled.
_on_save_shader_button_pressed()
-func _on_preset_options_item_selected(index):
- selected_preset_name = preset_options.get_item_text(index)
- Globals.shader = ShaderPresets.presets[selected_preset_name]
- Globals.target_viewport.update()
- update()
- last_save_filepath = ""
-
func update():
- preset_options.clear()
- # the following lines are weird af
- var presets: Array[String] = []
- var current_p_idx = 0
- for p in ShaderPresets.presets:
- presets.append(p)
- if p == selected_preset_name:
- current_p_idx = len(presets) - 1
- preset_options.add_item(p)
- preset_options.select(current_p_idx)
- # weirdness ends here
code_editor.text = Globals.shader.code
func _on_open_shader_button_pressed():
open_shader_dialog.show()
func _on_save_shader_button_pressed():
- if last_save_filepath == "":
- save_shader_dialog.current_file = selected_preset_name + "_custom.gdshader"
+ if Globals.last_shader_savepath == "":
+ save_shader_dialog.current_file = "shader.gdshader"
else:
- save_shader_dialog.current_path = last_save_filepath
+ save_shader_dialog.current_path = Globals.last_shader_savepath
save_shader_dialog.show()
func _on_open_shader_dialog_file_selected(path: String):
@@ -231,7 +210,7 @@ func _on_open_shader_dialog_file_selected(path: String):
Globals.cwd = path.substr(0, path.rfind("/"))
Globals.target_viewport.update()
update()
- last_save_filepath = path
+ Globals.last_shader_savepath = path
func _on_save_shader_dialog_file_selected(path):
print("Save ", path)
@@ -240,7 +219,7 @@ func _on_save_shader_dialog_file_selected(path):
file.store_string(content)
if "/" in path: # update current working directory
Globals.cwd = path.substr(0, path.rfind("/"))
- last_save_filepath = path
+ Globals.last_shader_savepath = path
func _on_apply_shader_button_pressed():
var shader = Shader.new()
diff --git a/src/Globals.gd b/src/Globals.gd
index 44e8681..0351452 100644
--- a/src/Globals.gd
+++ b/src/Globals.gd
@@ -1,6 +1,8 @@
extends Node
var camera_freeze = false
-@onready var shader: Shader = ShaderPresets.presets[ShaderPresets.default_preset]
+@onready var shader: Shader = load("res://src/shaders/empty.gdshader")
var target_viewport: SubViewport
var cwd = "."
+var last_image_savepath = ""
+var last_shader_savepath = ""
diff --git a/src/ImageViewport.gd b/src/ImageViewport.gd
index 1db1e55..207d283 100644
--- a/src/ImageViewport.gd
+++ b/src/ImageViewport.gd
@@ -1,46 +1,71 @@
extends SubViewport
-@onready var image_sprite = $ImageSprite
+@onready var camera = %Camera
+@onready var image_sprite = %ImageSprite
var image_original_tex: ImageTexture
var image_result: Image
-var load_uniform_regex: RegEx
+var load_regex: RegEx
+var load_additional_regex: RegEx
+var last_tex_path = ""
func _ready():
- load_uniform_regex = RegEx.new()
- load_uniform_regex.compile(r'\/\/!load\s(\w*)\s(.*)')
+ 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 set_original_image(image: Image):
- image_original_tex = ImageTexture.create_from_image(image)
- image_sprite.texture = image_original_tex
- image_sprite.offset = image_original_tex.get_size() / 2
- size = image_original_tex.get_size()
+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():
- if image_original_tex != null:
- image_sprite.texture = image_original_tex
- var mat = ShaderMaterial.new()
- mat.shader = Globals.shader
- # load images from //!load directives and apply them to
- # the material as shader parameters
- for m in load_uniform_regex.search_all(Globals.shader.code):
- # this only works for Linux!
- var img_path = m.strings[2]
- if !img_path.begins_with("/"):
- img_path = Globals.cwd + "/" + img_path.lstrip("./")
- #
- print("Load ", img_path)
- var u_image = Image.load_from_file(img_path)
- mat.set_shader_parameter(
- m.strings[1], # uniform param name
- ImageTexture.create_from_image(u_image))
- # assign material
- image_sprite.material = mat
- # Get viewport texture
- await RenderingServer.frame_post_draw # for good measure
- image_result = get_texture().get_image()
- image_sprite.material = null
- image_sprite.texture = ImageTexture.create_from_image(image_result)
+ # load images from //!load directive -> TEXTURE
+ var regex_match = load_regex.search(Globals.shader.code)
+ if regex_match == null: # Error!
+ print("Didn't find any load directives!")
+ 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
+ var mat = ShaderMaterial.new()
+ mat.shader = Globals.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)
+ mat.set_shader_parameter(
+ m.strings[1], # uniform param name
+ ImageTexture.create_from_image(u_image))
+ # assign material
+ image_sprite.material = mat
+ # Get viewport texture
+ await RenderingServer.frame_post_draw # for good measure
+ image_result = get_texture().get_image()
+ image_sprite.material = null
+ image_sprite.texture = ImageTexture.create_from_image(image_result)
func get_result():
return image_result
diff --git a/src/ImageViewportDisplays.gd b/src/ImageViewportDisplay.gd
similarity index 53%
rename from src/ImageViewportDisplays.gd
rename to src/ImageViewportDisplay.gd
index d4817ca..9edcf83 100644
--- a/src/ImageViewportDisplays.gd
+++ b/src/ImageViewportDisplay.gd
@@ -1,9 +1,7 @@
extends Sprite2D
-@onready var camera = get_parent().get_node("Camera")
-
-func _process(_delta):
- if camera.zoom.x >= 1.5:
+func update_zoom_texture_filter(zoom: Vector2):
+ if zoom.x >= 1.5:
texture_filter = TEXTURE_FILTER_NEAREST_WITH_MIPMAPS
else:
texture_filter = TEXTURE_FILTER_LINEAR
diff --git a/src/Main.gd b/src/Main.gd
index b930536..42be43b 100644
--- a/src/Main.gd
+++ b/src/Main.gd
@@ -1,33 +1,16 @@
extends Node2D
-@onready var camera = $Camera
-@onready var image_viewport = $ImageViewport
-@onready var ui_container = $UI_Layer/UserInterfaceContainer
-@onready var ui_control_fileopen = $UI_Layer/UserInterfaceContainer/OpenImageDialog
-@onready var ui_control_filesave = $UI_Layer/UserInterfaceContainer/SaveImageDialog
-var last_save_filepath = ""
+@onready var image_viewport = %ImageViewport
+@onready var ui_control_filesave = %SaveImageDialog
+
func _ready():
+ DisplayServer.window_set_min_size(Vector2i(900, 500))
Globals.target_viewport = image_viewport
-func _on_open_image_button_pressed():
- ui_control_fileopen.show()
-
-func _on_open_image_dialog_file_selected(path):
- print("Load ", path)
- var img = Image.new()
- var err = img.load(path)
- if err == OK:
- image_viewport.set_original_image(img)
- image_viewport.update()
- camera.fit_image()
- last_save_filepath = path
- else:
- print("An error occured!")
-
func _on_save_image_button_pressed():
if image_viewport.get_result() != null:
- ui_control_filesave.current_path = last_save_filepath
+ ui_control_filesave.current_path = Globals.last_image_savepath
ui_control_filesave.show()
func _on_save_image_dialog_file_selected(path):
@@ -36,4 +19,4 @@ func _on_save_image_dialog_file_selected(path):
if err != OK:
print("An error occured!")
else:
- last_save_filepath = path
+ Globals.last_image_savepath = path
diff --git a/src/presets/Presets.gd b/src/presets/Presets.gd
deleted file mode 100644
index c009bd2..0000000
--- a/src/presets/Presets.gd
+++ /dev/null
@@ -1,14 +0,0 @@
-extends Node
-
-const dir = "res://src/presets/shaders/"
-
-@onready var presets = {
- "Empty": load(dir + "empty.gdshader"),
- "Greyscale": load(dir + "greyscale.gdshader"),
- "Lowpass": load(dir + "lowpass.gdshader"),
- "Channel Offset": load(dir + "channel_offset.gdshader"),
- "RGB -> UV Distort": load(dir + "rgb_uv_distort.gdshader"),
- "Mix": load(dir + "mix.gdshader")
-}
-
-var default_preset: String = "Empty"
diff --git a/src/presets/shaders/empty.gdshader b/src/shaders/empty.gdshader
similarity index 77%
rename from src/presets/shaders/empty.gdshader
rename to src/shaders/empty.gdshader
index 0cb1281..be6c5cc 100644
--- a/src/presets/shaders/empty.gdshader
+++ b/src/shaders/empty.gdshader
@@ -1,5 +1,7 @@
shader_type canvas_item;
+//!load /path/to/your/image
+
void fragment() {
// Called for every pixel the material is visible on.
}