Removed all editor functionality and improved new viewer-only UI #54
This commit is contained in:
parent
e40ab18683
commit
9f5011aaac
21 changed files with 391 additions and 642 deletions
|
@ -11,11 +11,11 @@ config_version=5
|
||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="Fragmented"
|
config/name="Fragmented"
|
||||||
config/version="v8.2"
|
config/version="v9.0"
|
||||||
run/main_scene="res://scenes/main.tscn"
|
run/main_scene="res://src/scenes/main.tscn"
|
||||||
config/features=PackedStringArray("4.3", "Mobile")
|
config/features=PackedStringArray("4.3", "Mobile")
|
||||||
run/low_processor_mode=true
|
run/low_processor_mode=true
|
||||||
config/icon="res://assets/icon.png"
|
config/icon="res://src/assets/icon.png"
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ ShaderDirectiveParser="*res://src/ShaderDirectiveParser.gd"
|
||||||
|
|
||||||
[display]
|
[display]
|
||||||
|
|
||||||
window/size/viewport_width=704
|
window/size/viewport_width=640
|
||||||
window/size/viewport_height=704
|
window/size/viewport_height=672
|
||||||
window/energy_saving/keep_screen_on=false
|
window/energy_saving/keep_screen_on=false
|
||||||
window/subwindows/embed_subwindows=false
|
window/subwindows/embed_subwindows=false
|
||||||
window/vsync/vsync_mode=0
|
window/vsync/vsync_mode=0
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
[gd_scene load_steps=10 format=3 uid="uid://bjah7k4bxo044"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/Main.gd" id="1_2625y"]
|
|
||||||
[ext_resource type="Script" path="res://src/ImageCompositor.gd" id="2_4thch"]
|
|
||||||
[ext_resource type="Shader" path="res://src/shader/ivd_outline.gdshader" id="3_6xihe"]
|
|
||||||
[ext_resource type="Script" path="res://src/ImageViewportDisplay.gd" id="3_n4itb"]
|
|
||||||
[ext_resource type="Script" path="res://src/UIWindow.gd" id="6_8k0ha"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://btgits2mfup0h" path="res://scenes/ui_container.tscn" id="7_5ci0e"]
|
|
||||||
[ext_resource type="Script" path="res://src/Camera.gd" id="8_mls06"]
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_y2ea0"]
|
|
||||||
shader = ExtResource("3_6xihe")
|
|
||||||
shader_parameter/zoom_level = Vector2(1, 1)
|
|
||||||
|
|
||||||
[sub_resource type="ViewportTexture" id="ViewportTexture_lct1c"]
|
|
||||||
viewport_path = NodePath("Compositor")
|
|
||||||
|
|
||||||
[node name="Main" type="Node2D"]
|
|
||||||
script = ExtResource("1_2625y")
|
|
||||||
|
|
||||||
[node name="Compositor" type="SubViewport" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
script = ExtResource("2_4thch")
|
|
||||||
|
|
||||||
[node name="ImageViewportDisplay" type="Sprite2D" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
material = SubResource("ShaderMaterial_y2ea0")
|
|
||||||
texture = SubResource("ViewportTexture_lct1c")
|
|
||||||
script = ExtResource("3_n4itb")
|
|
||||||
|
|
||||||
[node name="Camera" type="Camera2D" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
script = ExtResource("8_mls06")
|
|
||||||
|
|
||||||
[node name="EditorWindow" type="Window" parent="."]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
disable_3d = true
|
|
||||||
position = Vector2i(48, 36)
|
|
||||||
size = Vector2i(704, 704)
|
|
||||||
visible = false
|
|
||||||
script = ExtResource("6_8k0ha")
|
|
||||||
|
|
||||||
[node name="UserInterfaceContainer" parent="EditorWindow" instance=ExtResource("7_5ci0e")]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
|
|
||||||
[connection signal="close_requested" from="EditorWindow" to="EditorWindow" method="_on_close_requested"]
|
|
|
@ -1,204 +0,0 @@
|
||||||
[gd_scene load_steps=3 format=3 uid="uid://btgits2mfup0h"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/UIAppVersion.gd" id="1_5qvnb"]
|
|
||||||
[ext_resource type="Script" path="res://src/Editor.gd" id="2_haub5"]
|
|
||||||
|
|
||||||
[node name="UserInterfaceContainer" type="Control"]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="AppName" type="Label" parent="."]
|
|
||||||
layout_mode = 0
|
|
||||||
offset_left = 24.0
|
|
||||||
offset_top = 16.0
|
|
||||||
offset_right = 208.0
|
|
||||||
offset_bottom = 48.0
|
|
||||||
theme_override_font_sizes/font_size = 20
|
|
||||||
text = "Fragmented"
|
|
||||||
vertical_alignment = 2
|
|
||||||
|
|
||||||
[node name="AppVersion" type="Label" parent="."]
|
|
||||||
layout_mode = 0
|
|
||||||
offset_left = 152.0
|
|
||||||
offset_top = 17.0
|
|
||||||
offset_right = 208.0
|
|
||||||
offset_bottom = 47.0
|
|
||||||
theme_override_font_sizes/font_size = 14
|
|
||||||
text = "v0
|
|
||||||
"
|
|
||||||
vertical_alignment = 2
|
|
||||||
script = ExtResource("1_5qvnb")
|
|
||||||
|
|
||||||
[node name="Editor" type="Control" parent="."]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_left = 24.0
|
|
||||||
offset_top = 64.0
|
|
||||||
offset_right = -24.0
|
|
||||||
offset_bottom = -16.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
script = ExtResource("2_haub5")
|
|
||||||
|
|
||||||
[node name="OpenShaderDialog" type="FileDialog" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
auto_translate_mode = 1
|
|
||||||
title = "Load Shader"
|
|
||||||
size = Vector2i(521, 175)
|
|
||||||
ok_button_text = "Open"
|
|
||||||
mode_overrides_title = false
|
|
||||||
file_mode = 0
|
|
||||||
access = 2
|
|
||||||
filters = PackedStringArray("*.gdshader")
|
|
||||||
use_native_dialog = true
|
|
||||||
|
|
||||||
[node name="SaveShaderDialog" type="FileDialog" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
auto_translate_mode = 1
|
|
||||||
title = "Save Shader"
|
|
||||||
size = Vector2i(661, 175)
|
|
||||||
ok_button_text = "Save"
|
|
||||||
mode_overrides_title = false
|
|
||||||
access = 2
|
|
||||||
filters = PackedStringArray("*.gdshader")
|
|
||||||
use_native_dialog = true
|
|
||||||
|
|
||||||
[node name="SaveImageDialog" type="FileDialog" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
auto_translate_mode = 1
|
|
||||||
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="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_top = 48.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
theme_override_font_sizes/font_size = 14
|
|
||||||
placeholder_text = "// Test"
|
|
||||||
wrap_mode = 1
|
|
||||||
minimap_draw = true
|
|
||||||
minimap_width = 40
|
|
||||||
caret_blink = true
|
|
||||||
draw_control_chars = true
|
|
||||||
draw_tabs = true
|
|
||||||
draw_spaces = true
|
|
||||||
line_length_guidelines = Array[int]([80])
|
|
||||||
gutters_draw_line_numbers = true
|
|
||||||
code_completion_enabled = true
|
|
||||||
indent_automatic = true
|
|
||||||
auto_brace_completion_enabled = true
|
|
||||||
auto_brace_completion_highlight_matching = true
|
|
||||||
|
|
||||||
[node name="NewShaderButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
offset_right = 48.0
|
|
||||||
offset_bottom = 32.0
|
|
||||||
text = "New"
|
|
||||||
|
|
||||||
[node name="OpenShaderButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
offset_left = 56.0
|
|
||||||
offset_right = 112.0
|
|
||||||
offset_bottom = 32.0
|
|
||||||
text = "Open"
|
|
||||||
|
|
||||||
[node name="SaveShaderButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
offset_left = 120.0
|
|
||||||
offset_top = -1.0
|
|
||||||
offset_right = 176.0
|
|
||||||
offset_bottom = 31.0
|
|
||||||
text = "Save"
|
|
||||||
|
|
||||||
[node name="SaveShaderAsButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
offset_left = 184.0
|
|
||||||
offset_right = 263.0
|
|
||||||
offset_bottom = 32.0
|
|
||||||
text = "Save As"
|
|
||||||
|
|
||||||
[node name="SaveImageButton" type="Button" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 1
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
offset_left = -72.0
|
|
||||||
offset_bottom = 32.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
disabled = true
|
|
||||||
text = "Export"
|
|
||||||
|
|
||||||
[node name="FitImageButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 1
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
offset_left = -128.0
|
|
||||||
offset_right = -80.0
|
|
||||||
offset_bottom = 32.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
text = "Fit"
|
|
||||||
|
|
||||||
[node name="ApplyShaderButton" type="Button" parent="Editor"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 1
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
offset_left = -232.0
|
|
||||||
offset_right = -136.0
|
|
||||||
offset_bottom = 31.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
text = "Apply (F5)"
|
|
||||||
|
|
||||||
[node name="StatusIndicator" type="TextureButton" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 1
|
|
||||||
anchor_left = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
offset_left = -76.0
|
|
||||||
offset_top = 56.0
|
|
||||||
offset_right = -56.0
|
|
||||||
offset_bottom = 76.0
|
|
||||||
grow_horizontal = 0
|
|
||||||
disabled = true
|
|
||||||
ignore_texture_size = true
|
|
||||||
stretch_mode = 0
|
|
||||||
|
|
||||||
[node name="ErrorMessageDialog" type="AcceptDialog" parent="Editor"]
|
|
||||||
unique_name_in_owner = true
|
|
||||||
title = "Status"
|
|
||||||
initial_position = 2
|
|
||||||
size = Vector2i(256, 128)
|
|
||||||
popup_window = true
|
|
||||||
ok_button_text = "Close"
|
|
||||||
|
|
||||||
[connection signal="file_selected" from="Editor/OpenShaderDialog" to="Editor" method="_on_open_shader_dialog_file_selected"]
|
|
||||||
[connection signal="file_selected" from="Editor/SaveShaderDialog" to="Editor" method="_on_save_shader_dialog_file_selected"]
|
|
||||||
[connection signal="file_selected" from="Editor/SaveImageDialog" to="Editor" method="_on_save_image_dialog_file_selected"]
|
|
||||||
[connection signal="code_completion_requested" from="Editor/CodeEdit" to="Editor" method="_on_code_edit_code_completion_requested"]
|
|
||||||
[connection signal="pressed" from="Editor/NewShaderButton" to="Editor" method="_on_new_shader_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/OpenShaderButton" to="Editor" method="_on_open_shader_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/SaveShaderButton" to="Editor" method="_on_save_shader_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/SaveShaderAsButton" to="Editor" method="_on_save_shader_as_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/SaveImageButton" to="Editor" method="_on_save_image_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/FitImageButton" to="Editor" method="_on_fit_image_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/ApplyShaderButton" to="Editor" method="_on_apply_shader_button_pressed"]
|
|
||||||
[connection signal="pressed" from="Editor/StatusIndicator" to="Editor" method="_on_status_indicator_pressed"]
|
|
|
@ -1,9 +1,9 @@
|
||||||
extends Camera2D
|
extends Camera2D
|
||||||
|
|
||||||
var drag = false
|
|
||||||
|
|
||||||
@onready var image_viewport_display = %ImageViewportDisplay
|
@onready var image_viewport_display = %ImageViewportDisplay
|
||||||
|
|
||||||
|
var drag = false
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if event.is_action_pressed("zoom_out"):
|
if event.is_action_pressed("zoom_out"):
|
||||||
zoom_out()
|
zoom_out()
|
||||||
|
@ -20,9 +20,11 @@ func fit_image():
|
||||||
if Filesystem.original_image != null:
|
if Filesystem.original_image != null:
|
||||||
var image_size = Filesystem.original_image.get_size()
|
var image_size = Filesystem.original_image.get_size()
|
||||||
var viewport_size = get_viewport_rect().size
|
var viewport_size = get_viewport_rect().size
|
||||||
var zoomf = viewport_size.x / image_size.x / 1.1
|
var zoomf = 1.0
|
||||||
if zoomf * image_size.y > viewport_size.y:
|
if viewport_size.x / image_size.x * image_size.y > viewport_size.y:
|
||||||
zoomf = viewport_size.y / image_size.y / 1.1
|
zoomf = viewport_size.y / image_size.y / 1.25
|
||||||
|
else:
|
||||||
|
zoomf = viewport_size.x / image_size.x / 1.2
|
||||||
self.zoom = Vector2(zoomf, zoomf)
|
self.zoom = Vector2(zoomf, zoomf)
|
||||||
self.global_position = Vector2(0, 0)
|
self.global_position = Vector2(0, 0)
|
||||||
|
|
||||||
|
|
307
src/Editor.gd
307
src/Editor.gd
|
@ -1,307 +0,0 @@
|
||||||
extends Control
|
|
||||||
|
|
||||||
@onready var code_editor = %CodeEdit
|
|
||||||
|
|
||||||
@onready var open_shader_dialog = %OpenShaderDialog
|
|
||||||
@onready var save_shader_dialog = %SaveShaderDialog
|
|
||||||
@onready var ui_control_filesave = %SaveImageDialog
|
|
||||||
|
|
||||||
@onready var save_image_button = %SaveImageButton
|
|
||||||
|
|
||||||
@onready var status_indicator = %StatusIndicator
|
|
||||||
@onready var error_msg_dialog = %ErrorMessageDialog
|
|
||||||
|
|
||||||
@onready var main = get_tree().root.get_node("Main")
|
|
||||||
@onready var compositor = main.get_node("%Compositor")
|
|
||||||
@onready var camera = main.get_node("%Camera")
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
var status_okay_texture: CompressedTexture2D = preload("uid://m1omb6g45vst")
|
|
||||||
var status_error_texture: CompressedTexture2D = preload("uid://04iv1gogpuhu")
|
|
||||||
|
|
||||||
# # # # # # # # # # #
|
|
||||||
# GDShader keywords #
|
|
||||||
# https://github.com/godotengine/godot/blob/e96ad5af98547df71b50c4c4695ac348638113e0/servers/rendering/shader_language.cpp
|
|
||||||
# https://github.com/godotengine/godot/blob/e96ad5af98547df71b50c4c4695ac348638113e0/servers/rendering/shader_types.cpp
|
|
||||||
#
|
|
||||||
const gdshader_boolean_values = [
|
|
||||||
"true", "false"
|
|
||||||
]
|
|
||||||
const gdshader_datatypes = [
|
|
||||||
"void",
|
|
||||||
"bool", "bvec2", "bvec3", "bvec4",
|
|
||||||
"int", "ivec2", "ivec3", "ivec4",
|
|
||||||
"uint", "uvec2", "uvec3", "uvec4",
|
|
||||||
"float", "vec2", "vec3", "vec4",
|
|
||||||
"mat2", "mat3", "mat4",
|
|
||||||
"sampler2D", "isampler2D", "usampler2D",
|
|
||||||
"sampler2DArray", "isampler2DArray", "usampler2DArray",
|
|
||||||
]
|
|
||||||
const gdshader_precision_modifiers = [
|
|
||||||
"lowp", "mediump", "heighp"
|
|
||||||
]
|
|
||||||
const gdshader_global_space_keywords = [
|
|
||||||
"uniform", "group_uniforms", "varying", "const",
|
|
||||||
"struct", "shader_type", "render_mode"
|
|
||||||
]
|
|
||||||
const gdshader_uniform_qualifiers = [
|
|
||||||
"instance", "global"
|
|
||||||
]
|
|
||||||
const gdshader_block_keywords = [
|
|
||||||
"if", "else",
|
|
||||||
"for", "while", "do",
|
|
||||||
"switch", "case",
|
|
||||||
"default", "break", "continue",
|
|
||||||
"return", "discard"
|
|
||||||
]
|
|
||||||
const gdshader_function_specifier_keywords = [
|
|
||||||
"in", "out", "inout"
|
|
||||||
]
|
|
||||||
const gdshader_hints = [
|
|
||||||
"source_color", "hint_range", "instance_index"
|
|
||||||
]
|
|
||||||
const gdshader_sampler_hints = [
|
|
||||||
"hint_normal",
|
|
||||||
"hint_default_white", "hint_default_black", "hint_default_transparent",
|
|
||||||
"hint_anisotropy",
|
|
||||||
"hint_roughness_r", "hint_roughness_g", "hint_roughness_b", "hint_roughness_a",
|
|
||||||
"hint_roughness_normal", "hint_roughness_gray",
|
|
||||||
"hint_screen_texture", "hint_normal_roughness_texture",
|
|
||||||
"hint_depth_texture",
|
|
||||||
"filter_nearest", "filter_linear",
|
|
||||||
"filter_nearest_mipmap", "filter_linear_mipmap",
|
|
||||||
"filter_nearest_mipmap_anisotropic", "filter_linear_mipmap_anisotropic",
|
|
||||||
"repeat_enable", "repeat_disable"
|
|
||||||
]
|
|
||||||
const gdshader_builtin_functions = [
|
|
||||||
"radians", "degrees",
|
|
||||||
"sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh",
|
|
||||||
"asinh", "acosh", "atanh",
|
|
||||||
"pow", "exp", "exp2", "log", "log2", "sqrt", "inversesqrt",
|
|
||||||
"abs", "sign", "floor", "trunc", "round", "roundEven", "ceil", "fract",
|
|
||||||
"mod", "modf", "min", "max", "clamp",
|
|
||||||
"mix", "step", "smoothstep",
|
|
||||||
"isnan", "isinf",
|
|
||||||
"floatBitsToInt", "floatBitsToUint", "intBitsToFloat", "uintBitsToFloat",
|
|
||||||
"length", "distance",
|
|
||||||
"dot", "cross",
|
|
||||||
"normalize", "reflect", "refract", "faceforward",
|
|
||||||
"matrixCompMult", "outerProduct", "transpose",
|
|
||||||
"determinant", "inverse",
|
|
||||||
"lessThan", "greaterThan", "lessThanEqual", "greaterThanEqual",
|
|
||||||
"equal", "notEqual",
|
|
||||||
"any", "all", "not",
|
|
||||||
"textureSize", "texture", "textureProj", "textureLod", "texelFetch",
|
|
||||||
"textureProjLod", "textureGrad", "textureProjGrad", "textureGather",
|
|
||||||
"textureQueryLod", "textureQueryLevels",
|
|
||||||
"dFdx", "dFdxCoarse", "dFdxFine", "dFdy", "dFdyCoarse", "dFdyFine",
|
|
||||||
"fwidth", "fwidthCoarse", "fwidthFine"
|
|
||||||
]
|
|
||||||
const gdshader_sub_functions = [
|
|
||||||
"length", "fma",
|
|
||||||
"packHalf2x16", "packUnorm2x16", "packSnorm2x16", "packUnorm4x8", "packSnorm4x8",
|
|
||||||
"unpackHalf2x16", "unpackUnorm2x16", "unpackSnorm2x16", "unpackUnorm4x8", "unpackSnorm4x8",
|
|
||||||
"bitfieldExtract", "bitfieldInsert", "bitfieldReverse", "bitCount",
|
|
||||||
"findLSB", "findMSB",
|
|
||||||
"umulExtended", "imulExtended",
|
|
||||||
"uaddCarry", "usubBorrow",
|
|
||||||
"ldexp", "frexp"
|
|
||||||
]
|
|
||||||
const gdshader_builtins = [
|
|
||||||
"TIME", "PI", "TAU", "E",
|
|
||||||
"VERTEX",
|
|
||||||
"UV",
|
|
||||||
"COLOR",
|
|
||||||
"POINT_SIZE",
|
|
||||||
"AT_LIGHT_PASS",
|
|
||||||
"TEXTURE_PIXEL_SIZE",
|
|
||||||
"SHADOW_VERTEX", "LIGHT_VERTEX",
|
|
||||||
"FRAGCOORD",
|
|
||||||
"NORMAL", "NORMAL_MAP", "NORMAL_MAP_DEPTH",
|
|
||||||
"TEXTURE",
|
|
||||||
"POINT_COORD",
|
|
||||||
"SPECULAR_SHININESS"
|
|
||||||
]
|
|
||||||
const gdshader_preprocessor = [
|
|
||||||
"define", "undef", "include", "pragma",
|
|
||||||
"if", "elif", "ifdef", "ifndef", "else", "endif"
|
|
||||||
]
|
|
||||||
# shaderlib
|
|
||||||
var shaderlib_regex = {} # auto-generated
|
|
||||||
const shaderlib_functions = {
|
|
||||||
"blur": ["gaussian_blur"],
|
|
||||||
"common": ["alpha_blend", "cbrt"],
|
|
||||||
"denoise": ["smart_denoise"],
|
|
||||||
"hsv": ["rgb2hsv", "hsv2rgb",],
|
|
||||||
"kuwahara": ["kuwahara",],
|
|
||||||
"oklab": ["oklab2rgb", "rgb2oklab", "oklab2oklch", "oklch2oklab"],
|
|
||||||
"pixelate": ["pixelate"],
|
|
||||||
"place_texture": ["place_texture"],
|
|
||||||
}
|
|
||||||
#
|
|
||||||
# configure Highlighter
|
|
||||||
#
|
|
||||||
class ShaderSyntaxHighlighter extends CodeHighlighter:
|
|
||||||
func _init():
|
|
||||||
add_color_region("//", "", Color.WEB_GRAY, true)
|
|
||||||
add_color_region("/*", "*/", Color.WEB_GRAY, false)
|
|
||||||
function_color = Color.INDIAN_RED
|
|
||||||
for k in gdshader_boolean_values:
|
|
||||||
keyword_colors[k] = Color.INDIAN_RED
|
|
||||||
for k in ( gdshader_datatypes
|
|
||||||
+ gdshader_hints
|
|
||||||
+ gdshader_sampler_hints
|
|
||||||
+ gdshader_global_space_keywords
|
|
||||||
+ gdshader_function_specifier_keywords
|
|
||||||
+ gdshader_precision_modifiers
|
|
||||||
+ gdshader_uniform_qualifiers):
|
|
||||||
keyword_colors[k] = Color.ORCHID;
|
|
||||||
for k in gdshader_block_keywords:
|
|
||||||
keyword_colors[k] = Color.CORAL
|
|
||||||
for k in gdshader_builtins:
|
|
||||||
keyword_colors[k] = Color.DARK_TURQUOISE
|
|
||||||
member_variable_color = Color.LIGHT_BLUE
|
|
||||||
number_color = Color.AQUA
|
|
||||||
symbol_color = Color.GRAY
|
|
||||||
#
|
|
||||||
# and code completion
|
|
||||||
#
|
|
||||||
func _on_code_edit_code_completion_requested():
|
|
||||||
for k in gdshader_boolean_values:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, k, k, Color.INDIAN_RED)
|
|
||||||
for k in ( gdshader_datatypes
|
|
||||||
+ gdshader_hints
|
|
||||||
+ gdshader_sampler_hints
|
|
||||||
+ gdshader_global_space_keywords
|
|
||||||
+ gdshader_function_specifier_keywords
|
|
||||||
+ gdshader_precision_modifiers
|
|
||||||
+ gdshader_uniform_qualifiers):
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_CLASS, k, k, Color.ORCHID)
|
|
||||||
for k in gdshader_block_keywords:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, k, k, Color.CORAL)
|
|
||||||
for k in gdshader_builtins:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_CONSTANT, k, k, Color.DARK_TURQUOISE)
|
|
||||||
for k in gdshader_builtin_functions + gdshader_sub_functions:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_FUNCTION, k, k+"(", Color.INDIAN_RED)
|
|
||||||
for k in gdshader_preprocessor:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, "#" + k, k)
|
|
||||||
# shaderlib #
|
|
||||||
var shader_code = code_editor.text
|
|
||||||
for key in shaderlib_regex:
|
|
||||||
if shaderlib_regex[key].search(shader_code) != null:
|
|
||||||
if key in shaderlib_functions:
|
|
||||||
for k in shaderlib_functions[key]:
|
|
||||||
code_editor.code_completion_prefixes.append(k)
|
|
||||||
code_editor.add_code_completion_option(CodeEdit.KIND_FUNCTION, k, k+"(", Color.INDIAN_RED)
|
|
||||||
# # # # # # #
|
|
||||||
code_editor.update_code_completion_options(true)
|
|
||||||
#
|
|
||||||
# # # # # # # # # # # #
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
# generate regexes
|
|
||||||
for k in shaderlib_functions:
|
|
||||||
shaderlib_regex[k] = RegEx.create_from_string(
|
|
||||||
r'\s*\#include\s+\"res\:\/\/shaderlib\/' + k + r'\.gdshaderinc\"')
|
|
||||||
#
|
|
||||||
code_editor.code_completion_enabled = true
|
|
||||||
code_editor.syntax_highlighter = ShaderSyntaxHighlighter.new()
|
|
||||||
self.update_code_edit()
|
|
||||||
|
|
||||||
func _input(event):
|
|
||||||
if event.is_action_pressed("apply_shader"):
|
|
||||||
_on_apply_shader_button_pressed()
|
|
||||||
elif event.is_action_pressed("save_shader"):
|
|
||||||
accept_event() # Event is now handled.
|
|
||||||
_on_save_shader_button_pressed()
|
|
||||||
|
|
||||||
func update_code_edit():
|
|
||||||
code_editor.text = Filesystem.shader_code
|
|
||||||
|
|
||||||
enum Status {OKAY, ERROR, UNKNOWN = -1}
|
|
||||||
|
|
||||||
func update_status(status: Status, msg: String = ""):
|
|
||||||
error_msg_dialog.dialog_text = msg
|
|
||||||
error_msg_dialog.reset_size()
|
|
||||||
if status == Status.OKAY:
|
|
||||||
status_indicator.texture_normal = status_okay_texture
|
|
||||||
elif status == Status.ERROR:
|
|
||||||
status_indicator.texture_normal = status_error_texture
|
|
||||||
else:
|
|
||||||
status_indicator.texture_normal = null
|
|
||||||
if msg == "":
|
|
||||||
status_indicator.disabled = true
|
|
||||||
else:
|
|
||||||
status_indicator.disabled = false
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
func _on_new_shader_button_pressed():
|
|
||||||
main.update_title()
|
|
||||||
Filesystem.reset()
|
|
||||||
self.update_code_edit()
|
|
||||||
compositor.update()
|
|
||||||
update_status(Status.UNKNOWN)
|
|
||||||
|
|
||||||
func _on_open_shader_button_pressed():
|
|
||||||
open_shader_dialog.show()
|
|
||||||
|
|
||||||
func _on_save_shader_button_pressed():
|
|
||||||
Filesystem.shader_code = code_editor.text
|
|
||||||
if Filesystem.last_shader_savepath == "":
|
|
||||||
_on_save_shader_as_button_pressed()
|
|
||||||
else:
|
|
||||||
_on_save_shader_dialog_file_selected(Filesystem.last_shader_savepath)
|
|
||||||
|
|
||||||
func _on_save_shader_as_button_pressed() -> void:
|
|
||||||
Filesystem.shader_code = code_editor.text
|
|
||||||
if Filesystem.last_shader_savepath == "":
|
|
||||||
save_shader_dialog.current_file = "filter.gdshader"
|
|
||||||
else:
|
|
||||||
save_shader_dialog.current_path = Filesystem.last_shader_savepath
|
|
||||||
save_shader_dialog.show()
|
|
||||||
|
|
||||||
func _on_fit_image_button_pressed():
|
|
||||||
camera.fit_image()
|
|
||||||
|
|
||||||
func _on_apply_shader_button_pressed():
|
|
||||||
save_image_button.disabled = true
|
|
||||||
Filesystem.shader_code = code_editor.text
|
|
||||||
var errors = await compositor.update()
|
|
||||||
if len(errors) > 0:
|
|
||||||
update_status(Status.ERROR, "\n".join(errors))
|
|
||||||
else:
|
|
||||||
update_status(Status.OKAY)
|
|
||||||
save_image_button.disabled = false
|
|
||||||
|
|
||||||
func _on_save_image_button_pressed():
|
|
||||||
if Filesystem.result != null:
|
|
||||||
ui_control_filesave.current_path = Filesystem.last_image_savepath
|
|
||||||
ui_control_filesave.show()
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
func _on_open_shader_dialog_file_selected(path: String):
|
|
||||||
Filesystem.load_shader(path)
|
|
||||||
main.update_title(path.split("/")[-1])
|
|
||||||
self.update_code_edit()
|
|
||||||
self._on_apply_shader_button_pressed()
|
|
||||||
|
|
||||||
func _on_save_shader_dialog_file_selected(path):
|
|
||||||
Filesystem.save_shader(path)
|
|
||||||
main.update_title(path.split("/")[-1])
|
|
||||||
|
|
||||||
func _on_save_image_dialog_file_selected(path):
|
|
||||||
Filesystem.save_result(path)
|
|
||||||
|
|
||||||
#
|
|
||||||
|
|
||||||
func _on_status_indicator_pressed() -> void:
|
|
||||||
error_msg_dialog.show()
|
|
|
@ -1,25 +1,34 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
@onready var template_shader: Shader = load("res://src/shader/template.gdshader")
|
var cwd = "."
|
||||||
@onready var shader_code: String = template_shader.code
|
|
||||||
|
var shader_path = "":
|
||||||
|
get():
|
||||||
|
return shader_path
|
||||||
|
set(v):
|
||||||
|
var old = shader_path
|
||||||
|
shader_path = v
|
||||||
|
if "/" in v: # update current working directory
|
||||||
|
cwd = v.substr(0, v.rfind("/"))
|
||||||
|
if old != shader_path:
|
||||||
|
store_last_opened_file()
|
||||||
|
|
||||||
|
var shader_code: String:
|
||||||
|
get():
|
||||||
|
print("Load ", shader_path)
|
||||||
|
var file = FileAccess.open(shader_path, FileAccess.READ)
|
||||||
|
if file != null:
|
||||||
|
return file.get_as_text()
|
||||||
|
else: return ""
|
||||||
|
|
||||||
var original_image: ImageTexture
|
var original_image: ImageTexture
|
||||||
|
|
||||||
var additional_images: Dictionary
|
var additional_images: Dictionary
|
||||||
var result: Image
|
var result: Image
|
||||||
|
|
||||||
var cwd = "."
|
|
||||||
var last_image_savepath = ""
|
var last_image_savepath = ""
|
||||||
var last_shader_savepath = ""
|
|
||||||
var last_original_image_path = ""
|
var last_original_image_path = ""
|
||||||
|
|
||||||
func reset():
|
|
||||||
self.shader_code = self.template_shader.code
|
|
||||||
self.last_image_savepath = ""
|
|
||||||
self.last_shader_savepath = ""
|
|
||||||
self.last_original_image_path = ""
|
|
||||||
self.original_image = null
|
|
||||||
self.result = null
|
|
||||||
|
|
||||||
func get_absolute_path(p: String) -> String:
|
func get_absolute_path(p: String) -> String:
|
||||||
# this only works on Linux!
|
# this only works on Linux!
|
||||||
if !p.begins_with("/"):
|
if !p.begins_with("/"):
|
||||||
|
@ -27,14 +36,14 @@ func get_absolute_path(p: String) -> String:
|
||||||
return p
|
return p
|
||||||
|
|
||||||
func load_original_image(path: String) -> String: # returns an error message
|
func load_original_image(path: String) -> String: # returns an error message
|
||||||
|
print("Load ", path)
|
||||||
var img = Image.new()
|
var img = Image.new()
|
||||||
var err = img.load(path)
|
var err = img.load(path)
|
||||||
if err == OK:
|
if err == OK:
|
||||||
original_image = ImageTexture.create_from_image(img)
|
original_image = ImageTexture.create_from_image(img)
|
||||||
if path != self.last_original_image_path:
|
if self.last_image_savepath == "" or path != self.last_original_image_path:
|
||||||
self.last_original_image_path = path
|
|
||||||
if self.last_image_savepath == "":
|
|
||||||
self.last_image_savepath = path
|
self.last_image_savepath = path
|
||||||
|
self.last_original_image_path = path
|
||||||
return ""
|
return ""
|
||||||
return error_string(err) + " " + path
|
return error_string(err) + " " + path
|
||||||
|
|
||||||
|
@ -42,6 +51,7 @@ func clear_additional_images():
|
||||||
additional_images.clear()
|
additional_images.clear()
|
||||||
|
|
||||||
func load_additional_image(key: String, path: String) -> String: # returns Error Message String
|
func load_additional_image(key: String, path: String) -> String: # returns Error Message String
|
||||||
|
print("Load ", path)
|
||||||
var img = Image.new()
|
var img = Image.new()
|
||||||
var err = img.load(path)
|
var err = img.load(path)
|
||||||
if err == OK:
|
if err == OK:
|
||||||
|
@ -58,33 +68,13 @@ func save_result(path: String):
|
||||||
else:
|
else:
|
||||||
self.last_image_savepath = path
|
self.last_image_savepath = path
|
||||||
|
|
||||||
func load_shader(path: String):
|
|
||||||
print("Load ", path)
|
|
||||||
var file = FileAccess.open(path, FileAccess.READ)
|
|
||||||
if file != null:
|
|
||||||
self.shader_code = file.get_as_text()
|
|
||||||
if "/" in path: # update current working directory
|
|
||||||
self.cwd = path.substr(0, path.rfind("/"))
|
|
||||||
self.last_shader_savepath = path
|
|
||||||
store_last_opened_file()
|
|
||||||
|
|
||||||
func save_shader(path: String):
|
|
||||||
print("Save ", path)
|
|
||||||
var file = FileAccess.open(path, FileAccess.WRITE)
|
|
||||||
file.store_string(self.shader_code)
|
|
||||||
file.flush()
|
|
||||||
if "/" in path: # update current working directory
|
|
||||||
self.cwd = path.substr(0, path.rfind("/"))
|
|
||||||
self.last_shader_savepath = path
|
|
||||||
store_last_opened_file()
|
|
||||||
|
|
||||||
func store_last_opened_file():
|
func store_last_opened_file():
|
||||||
var f = FileAccess.open("user://last_opened", FileAccess.WRITE)
|
var f = FileAccess.open("user://last_opened", FileAccess.WRITE)
|
||||||
if f != null:
|
if f != null:
|
||||||
f.store_pascal_string(last_shader_savepath)
|
f.store_pascal_string(shader_path)
|
||||||
f.flush()
|
f.flush()
|
||||||
|
|
||||||
func remember_last_opened_file():
|
func remember_last_opened_file():
|
||||||
var f = FileAccess.open("user://last_opened", FileAccess.READ)
|
var f = FileAccess.open("user://last_opened", FileAccess.READ)
|
||||||
if f != null:
|
if f != null:
|
||||||
last_shader_savepath = f.get_pascal_string()
|
shader_path = f.get_pascal_string()
|
||||||
|
|
|
@ -45,8 +45,11 @@ func inject_step_uniform(shader_code: String) -> Shader:
|
||||||
return shader
|
return shader
|
||||||
|
|
||||||
func update(overwrite_image_path: String = "") -> Array: # returns error messages (strings)
|
func update(overwrite_image_path: String = "") -> Array: # returns error messages (strings)
|
||||||
|
var original_shader_code = Filesystem.shader_code # read from disk
|
||||||
|
if original_shader_code == "":
|
||||||
|
return ["No shader loaded!"]
|
||||||
# inject STEP uniform & get number of steps
|
# inject STEP uniform & get number of steps
|
||||||
var shader: Shader = inject_step_uniform(Filesystem.shader_code)
|
var shader: Shader = inject_step_uniform(original_shader_code)
|
||||||
var steps: int = ShaderDirectiveParser.parse_steps_directive(shader.code)
|
var steps: int = ShaderDirectiveParser.parse_steps_directive(shader.code)
|
||||||
# validate shader
|
# validate shader
|
||||||
if not validate_shader_compilation(shader):
|
if not validate_shader_compilation(shader):
|
||||||
|
|
14
src/Main.gd
14
src/Main.gd
|
@ -4,8 +4,6 @@ const BATCH_MODE_SUPPORTED_EXTS = [
|
||||||
".bmp", ".dds", ".exr", ".hdr", ".jpeg", ".jpg", ".ktx", ".png", ".svg", ".webp"
|
".bmp", ".dds", ".exr", ".hdr", ".jpeg", ".jpg", ".ktx", ".png", ".svg", ".webp"
|
||||||
]
|
]
|
||||||
|
|
||||||
@onready var editor_window = %EditorWindow
|
|
||||||
@onready var ui_container = %UserInterfaceContainer
|
|
||||||
@onready var app_name = ProjectSettings.get_setting("application/config/name")
|
@onready var app_name = ProjectSettings.get_setting("application/config/name")
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
@ -139,22 +137,12 @@ func cli_dump_shaderlib():
|
||||||
|
|
||||||
func prepare_gui():
|
func prepare_gui():
|
||||||
update_title()
|
update_title()
|
||||||
# position windows
|
|
||||||
get_window().position = Vector2i(
|
|
||||||
editor_window.position.x + editor_window.size.x + 50,
|
|
||||||
editor_window.position.y)
|
|
||||||
get_window().min_size = Vector2i(400, 400)
|
|
||||||
editor_window.min_size = Vector2i(560, 400)
|
|
||||||
editor_window.show()
|
|
||||||
# Load last opened file
|
# Load last opened file
|
||||||
Filesystem.remember_last_opened_file()
|
Filesystem.remember_last_opened_file()
|
||||||
if Filesystem.last_shader_savepath != "":
|
%MainUI._on_apply_shader_button_pressed()
|
||||||
ui_container.get_node("Editor")._on_open_shader_dialog_file_selected(Filesystem.last_shader_savepath)
|
|
||||||
|
|
||||||
func update_title(current_file: String = ""):
|
func update_title(current_file: String = ""):
|
||||||
if current_file == "":
|
if current_file == "":
|
||||||
get_window().title = app_name + " - Viewer"
|
get_window().title = app_name + " - Viewer"
|
||||||
editor_window.title = app_name + " - Editor"
|
|
||||||
else:
|
else:
|
||||||
get_window().title = current_file + " - " + app_name + " - Viewer"
|
get_window().title = current_file + " - " + app_name + " - Viewer"
|
||||||
editor_window.title = current_file + " - " + app_name + " - Editor"
|
|
||||||
|
|
99
src/MainUI.gd
Normal file
99
src/MainUI.gd
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
extends Control
|
||||||
|
|
||||||
|
@onready var open_shader_dialog = %OpenShaderDialog
|
||||||
|
@onready var save_image_dialog = %SaveImageDialog
|
||||||
|
|
||||||
|
@onready var open_shader_button = %OpenShaderButton
|
||||||
|
@onready var save_image_button = %SaveImageButton
|
||||||
|
@onready var fit_image_button = %FitImageButton
|
||||||
|
@onready var apply_shader_button = %ApplyShaderButton
|
||||||
|
|
||||||
|
@onready var status_indicator = %StatusIndicator
|
||||||
|
@onready var error_msg_dialog = %ErrorMessageDialog
|
||||||
|
|
||||||
|
@onready var main = get_tree().root.get_node("Main")
|
||||||
|
@onready var compositor = %Compositor
|
||||||
|
@onready var camera = %Camera
|
||||||
|
|
||||||
|
var status_okay_texture: CompressedTexture2D = preload("uid://m1omb6g45vst")
|
||||||
|
var status_error_texture: CompressedTexture2D = preload("uid://04iv1gogpuhu")
|
||||||
|
|
||||||
|
enum Status {OKAY, ERROR, UNKNOWN = -1}
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
func _input(event):
|
||||||
|
if event.is_action_pressed("apply_shader"):
|
||||||
|
_on_apply_shader_button_pressed()
|
||||||
|
elif event.is_action_pressed("save_shader"):
|
||||||
|
accept_event() # Event is now handled.
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
func set_buttons_disabled(disabled: bool):
|
||||||
|
for b in [open_shader_button, save_image_button, fit_image_button, apply_shader_button, status_indicator]:
|
||||||
|
b.disabled = disabled
|
||||||
|
|
||||||
|
func _on_open_shader_button_pressed():
|
||||||
|
set_buttons_disabled(true)
|
||||||
|
open_shader_dialog.show()
|
||||||
|
|
||||||
|
func _on_fit_image_button_pressed():
|
||||||
|
camera.fit_image()
|
||||||
|
|
||||||
|
func _on_apply_shader_button_pressed():
|
||||||
|
set_buttons_disabled(true)
|
||||||
|
var errors = await compositor.update()
|
||||||
|
set_buttons_disabled(false)
|
||||||
|
if len(errors) > 0:
|
||||||
|
update_status(Status.ERROR, "\n".join(errors))
|
||||||
|
else:
|
||||||
|
update_status(Status.OKAY)
|
||||||
|
status_indicator.disabled = true
|
||||||
|
|
||||||
|
func _on_save_image_button_pressed():
|
||||||
|
if Filesystem.result != null:
|
||||||
|
set_buttons_disabled(true)
|
||||||
|
save_image_dialog.current_path = Filesystem.last_image_savepath
|
||||||
|
save_image_dialog.show()
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
func _on_open_shader_dialog_file_selected(path: String):
|
||||||
|
Filesystem.shader_path = path
|
||||||
|
main.update_title(path.split("/")[-1])
|
||||||
|
self._on_apply_shader_button_pressed()
|
||||||
|
|
||||||
|
func _on_open_shader_dialog_canceled() -> void:
|
||||||
|
set_buttons_disabled(false)
|
||||||
|
|
||||||
|
func _on_open_shader_dialog_confirmed() -> void:
|
||||||
|
set_buttons_disabled(false)
|
||||||
|
|
||||||
|
func _on_save_image_dialog_file_selected(path):
|
||||||
|
Filesystem.save_result(path)
|
||||||
|
|
||||||
|
func _on_save_image_dialog_canceled() -> void:
|
||||||
|
set_buttons_disabled(false)
|
||||||
|
|
||||||
|
func _on_save_image_dialog_confirmed() -> void:
|
||||||
|
set_buttons_disabled(false)
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
func update_status(status: Status, msg: String = ""):
|
||||||
|
error_msg_dialog.dialog_text = msg
|
||||||
|
error_msg_dialog.reset_size()
|
||||||
|
if status == Status.OKAY:
|
||||||
|
status_indicator.texture_normal = status_okay_texture
|
||||||
|
elif status == Status.ERROR:
|
||||||
|
status_indicator.texture_normal = status_error_texture
|
||||||
|
else:
|
||||||
|
status_indicator.texture_normal = null
|
||||||
|
if msg == "":
|
||||||
|
status_indicator.disabled = true
|
||||||
|
else:
|
||||||
|
status_indicator.disabled = false
|
||||||
|
|
||||||
|
func _on_status_indicator_pressed() -> void:
|
||||||
|
error_msg_dialog.show()
|
|
@ -1,4 +0,0 @@
|
||||||
extends Label
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
text = ProjectSettings.get_setting("application/config/version")
|
|
|
@ -1,4 +0,0 @@
|
||||||
extends Window
|
|
||||||
|
|
||||||
func _on_close_requested() -> void:
|
|
||||||
get_tree().quit()
|
|
8
src/VersionLabel.gd
Normal file
8
src/VersionLabel.gd
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
extends Label
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
text = ProjectSettings.get_setting("application/config/name") \
|
||||||
|
+ " " \
|
||||||
|
+ ProjectSettings.get_setting("application/config/version") \
|
||||||
|
+ " | Godot " \
|
||||||
|
+ Engine.get_version_info()["string"]
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://04iv1gogpuhu"
|
uid="uid://04iv1gogpuhu"
|
||||||
path="res://.godot/imported/error.svg-75fe5f417585e01e99de8885f1f45c3b.ctex"
|
path="res://.godot/imported/error.svg-28fb29635cf59d39cabf7052619f602f.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/error.svg"
|
source_file="res://src/assets/error.svg"
|
||||||
dest_files=["res://.godot/imported/error.svg-75fe5f417585e01e99de8885f1f45c3b.ctex"]
|
dest_files=["res://.godot/imported/error.svg-28fb29635cf59d39cabf7052619f602f.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 3 KiB |
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://kqwc4avs2xdp"
|
uid="uid://kqwc4avs2xdp"
|
||||||
path="res://.godot/imported/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.ctex"
|
path="res://.godot/imported/icon.png-d8298ab6eda392a806be6bb7eec65b9c.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/icon.png"
|
source_file="res://src/assets/icon.png"
|
||||||
dest_files=["res://.godot/imported/icon.png-b6a7fb2db36edd3d95dc42f1dc8c1c5d.ctex"]
|
dest_files=["res://.godot/imported/icon.png-d8298ab6eda392a806be6bb7eec65b9c.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://m1omb6g45vst"
|
uid="uid://m1omb6g45vst"
|
||||||
path="res://.godot/imported/okay.svg-7f6df15523471a86f27b6817e9528a4e.ctex"
|
path="res://.godot/imported/okay.svg-de66a022ef37753b085371b7c60aefd1.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/okay.svg"
|
source_file="res://src/assets/okay.svg"
|
||||||
dest_files=["res://.godot/imported/okay.svg-7f6df15523471a86f27b6817e9528a4e.ctex"]
|
dest_files=["res://.godot/imported/okay.svg-de66a022ef37753b085371b7c60aefd1.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
174
src/scenes/main.tscn
Normal file
174
src/scenes/main.tscn
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
[gd_scene load_steps=12 format=3 uid="uid://bjah7k4bxo044"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://src/Main.gd" id="1_64y3g"]
|
||||||
|
[ext_resource type="Script" path="res://src/ImageCompositor.gd" id="2_4ykh7"]
|
||||||
|
[ext_resource type="Shader" path="res://src/shader/ivd_outline.gdshader" id="3_0fllm"]
|
||||||
|
[ext_resource type="Script" path="res://src/ImageViewportDisplay.gd" id="4_pbpx2"]
|
||||||
|
[ext_resource type="Script" path="res://src/Camera.gd" id="5_hkdq6"]
|
||||||
|
[ext_resource type="Theme" uid="uid://cwqlns34rj3vx" path="res://src/theme.tres" id="6_rjp5f"]
|
||||||
|
[ext_resource type="Script" path="res://src/MainUI.gd" id="7_5puhk"]
|
||||||
|
[ext_resource type="Script" path="res://src/VersionLabel.gd" id="8_kod8x"]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_y2ea0"]
|
||||||
|
shader = ExtResource("3_0fllm")
|
||||||
|
shader_parameter/zoom_level = Vector2(1, 1)
|
||||||
|
|
||||||
|
[sub_resource type="ViewportTexture" id="ViewportTexture_lct1c"]
|
||||||
|
viewport_path = NodePath("Compositor")
|
||||||
|
|
||||||
|
[sub_resource type="LabelSettings" id="LabelSettings_6o860"]
|
||||||
|
font_size = 12
|
||||||
|
font_color = Color(1, 1, 1, 0.509804)
|
||||||
|
shadow_color = Color(0, 0, 0, 1)
|
||||||
|
|
||||||
|
[node name="Main" type="Node2D"]
|
||||||
|
script = ExtResource("1_64y3g")
|
||||||
|
|
||||||
|
[node name="Compositor" type="SubViewport" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
script = ExtResource("2_4ykh7")
|
||||||
|
|
||||||
|
[node name="ImageViewportDisplay" type="Sprite2D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
material = SubResource("ShaderMaterial_y2ea0")
|
||||||
|
texture = SubResource("ViewportTexture_lct1c")
|
||||||
|
script = ExtResource("4_pbpx2")
|
||||||
|
|
||||||
|
[node name="Camera" type="Camera2D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
offset = Vector2(0, -64)
|
||||||
|
script = ExtResource("5_hkdq6")
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="MainUI" type="Control" parent="CanvasLayer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
pivot_offset = Vector2(320, 320)
|
||||||
|
theme = ExtResource("6_rjp5f")
|
||||||
|
script = ExtResource("7_5puhk")
|
||||||
|
|
||||||
|
[node name="OpenShaderDialog" type="FileDialog" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
auto_translate_mode = 1
|
||||||
|
title = "Load Shader"
|
||||||
|
size = Vector2i(521, 175)
|
||||||
|
ok_button_text = "Open"
|
||||||
|
mode_overrides_title = false
|
||||||
|
file_mode = 0
|
||||||
|
access = 2
|
||||||
|
filters = PackedStringArray("*.gdshader")
|
||||||
|
use_native_dialog = true
|
||||||
|
|
||||||
|
[node name="SaveImageDialog" type="FileDialog" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
auto_translate_mode = 1
|
||||||
|
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="ErrorMessageDialog" type="AcceptDialog" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
auto_translate_mode = 1
|
||||||
|
title = "Status"
|
||||||
|
initial_position = 2
|
||||||
|
size = Vector2i(256, 128)
|
||||||
|
popup_window = true
|
||||||
|
ok_button_text = "Close"
|
||||||
|
|
||||||
|
[node name="OpenShaderButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
offset_left = 16.0
|
||||||
|
offset_top = 16.0
|
||||||
|
offset_right = 128.0
|
||||||
|
offset_bottom = 48.0
|
||||||
|
text = "Open Shader"
|
||||||
|
|
||||||
|
[node name="SaveImageButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
offset_left = 144.0
|
||||||
|
offset_top = 16.0
|
||||||
|
offset_right = 216.0
|
||||||
|
offset_bottom = 48.0
|
||||||
|
disabled = true
|
||||||
|
text = "Export"
|
||||||
|
|
||||||
|
[node name="FitImageButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -176.0
|
||||||
|
offset_top = 16.0
|
||||||
|
offset_right = -128.0
|
||||||
|
offset_bottom = 48.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
text = "Fit"
|
||||||
|
|
||||||
|
[node name="ApplyShaderButton" type="Button" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -112.0
|
||||||
|
offset_top = 16.0
|
||||||
|
offset_right = -16.0
|
||||||
|
offset_bottom = 48.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
text = "Apply (F5)"
|
||||||
|
|
||||||
|
[node name="StatusIndicator" type="TextureButton" parent="CanvasLayer/MainUI"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 1
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_left = -220.0
|
||||||
|
offset_top = 21.0
|
||||||
|
offset_right = -196.0
|
||||||
|
offset_bottom = 45.0
|
||||||
|
grow_horizontal = 0
|
||||||
|
disabled = true
|
||||||
|
ignore_texture_size = true
|
||||||
|
stretch_mode = 0
|
||||||
|
|
||||||
|
[node name="VersionLabel" type="Label" parent="CanvasLayer/MainUI"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 12
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 16.0
|
||||||
|
offset_top = -24.0
|
||||||
|
offset_right = -16.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 0
|
||||||
|
label_settings = SubResource("LabelSettings_6o860")
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
script = ExtResource("8_kod8x")
|
||||||
|
|
||||||
|
[connection signal="canceled" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_canceled"]
|
||||||
|
[connection signal="confirmed" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_confirmed"]
|
||||||
|
[connection signal="file_selected" from="CanvasLayer/MainUI/OpenShaderDialog" to="CanvasLayer/MainUI" method="_on_open_shader_dialog_file_selected"]
|
||||||
|
[connection signal="canceled" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_canceled"]
|
||||||
|
[connection signal="confirmed" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_confirmed"]
|
||||||
|
[connection signal="file_selected" from="CanvasLayer/MainUI/SaveImageDialog" to="CanvasLayer/MainUI" method="_on_save_image_dialog_file_selected"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/MainUI/OpenShaderButton" to="CanvasLayer/MainUI" method="_on_open_shader_button_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/MainUI/SaveImageButton" to="CanvasLayer/MainUI" method="_on_save_image_button_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/MainUI/FitImageButton" to="CanvasLayer/MainUI" method="_on_fit_image_button_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/MainUI/ApplyShaderButton" to="CanvasLayer/MainUI" method="_on_apply_shader_button_pressed"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/MainUI/StatusIndicator" to="CanvasLayer/MainUI" method="_on_status_indicator_pressed"]
|
|
@ -1,7 +0,0 @@
|
||||||
shader_type canvas_item;
|
|
||||||
|
|
||||||
//!load /path/to/your/image
|
|
||||||
|
|
||||||
void fragment() {
|
|
||||||
// Called for every pixel the material is visible on.
|
|
||||||
}
|
|
57
src/theme.tres
Normal file
57
src/theme.tres
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
[gd_resource type="Theme" load_steps=4 format=3 uid="uid://cwqlns34rj3vx"]
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bm5o2"]
|
||||||
|
content_margin_left = 4.0
|
||||||
|
content_margin_top = 4.0
|
||||||
|
content_margin_right = 4.0
|
||||||
|
content_margin_bottom = 4.0
|
||||||
|
bg_color = Color(0.1, 0.1, 0.1, 0.3)
|
||||||
|
border_width_left = 1
|
||||||
|
border_width_top = 1
|
||||||
|
border_width_right = 1
|
||||||
|
border_width_bottom = 1
|
||||||
|
border_color = Color(1, 1, 1, 0.27451)
|
||||||
|
corner_radius_top_left = 3
|
||||||
|
corner_radius_top_right = 3
|
||||||
|
corner_radius_bottom_right = 3
|
||||||
|
corner_radius_bottom_left = 3
|
||||||
|
corner_detail = 5
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_l0k8a"]
|
||||||
|
content_margin_left = 4.0
|
||||||
|
content_margin_top = 4.0
|
||||||
|
content_margin_right = 4.0
|
||||||
|
content_margin_bottom = 4.0
|
||||||
|
bg_color = Color(0.225, 0.225, 0.225, 0.6)
|
||||||
|
border_width_left = 1
|
||||||
|
border_width_top = 1
|
||||||
|
border_width_right = 1
|
||||||
|
border_width_bottom = 1
|
||||||
|
border_color = Color(1, 1, 1, 0.784314)
|
||||||
|
corner_radius_top_left = 3
|
||||||
|
corner_radius_top_right = 3
|
||||||
|
corner_radius_bottom_right = 3
|
||||||
|
corner_radius_bottom_left = 3
|
||||||
|
corner_detail = 5
|
||||||
|
|
||||||
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_1dkyv"]
|
||||||
|
content_margin_left = 4.0
|
||||||
|
content_margin_top = 4.0
|
||||||
|
content_margin_right = 4.0
|
||||||
|
content_margin_bottom = 4.0
|
||||||
|
bg_color = Color(0.1, 0.1, 0.1, 0.6)
|
||||||
|
border_width_left = 1
|
||||||
|
border_width_top = 1
|
||||||
|
border_width_right = 1
|
||||||
|
border_width_bottom = 1
|
||||||
|
border_color = Color(1, 1, 1, 0.509804)
|
||||||
|
corner_radius_top_left = 3
|
||||||
|
corner_radius_top_right = 3
|
||||||
|
corner_radius_bottom_right = 3
|
||||||
|
corner_radius_bottom_left = 3
|
||||||
|
corner_detail = 5
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
Button/styles/disabled = SubResource("StyleBoxFlat_bm5o2")
|
||||||
|
Button/styles/hover = SubResource("StyleBoxFlat_l0k8a")
|
||||||
|
Button/styles/normal = SubResource("StyleBoxFlat_1dkyv")
|
Loading…
Add table
Add a link
Reference in a new issue