Add project files

This commit is contained in:
ChaoticByte 2024-06-04 18:31:04 +02:00
parent 88517179f0
commit 68cccc2a62
17 changed files with 551 additions and 1 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

View file

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 Julian Müller Copyright (c) 2024 Julian Müller (ChaoticByte)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

1
icon.svg Normal file
View file

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z" fill="#478cbf"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

After

Width:  |  Height:  |  Size: 949 B

37
icon.svg.import Normal file
View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bye3mkghgc0mg"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

58
project.godot Normal file
View file

@ -0,0 +1,58 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="Glitch"
config/version="0.0.1s"
run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.2", "Mobile")
run/low_processor_mode=true
config/icon="res://icon.svg"
[autoload]
ShaderPresets="*res://src/presets/Presets.gd"
GlitchShader="*res://src/GlitchShader.gd"
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
window/energy_saving/keep_screen_on=false
[editor_plugins]
enabled=PackedStringArray()
[input]
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)
]
}
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)
]
}
drag={
"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":1,"position":Vector2(183, 23),"global_position":Vector2(187, 64),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
]
}
[rendering]
renderer/rendering_method="mobile"
textures/vram_compression/import_etc2_astc=true
textures/lossless_compression/force_png=true
environment/defaults/default_clear_color=Color(0, 0, 0, 1)

153
scenes/main.tscn Normal file
View file

@ -0,0 +1,153 @@
[gd_scene load_steps=9 format=3 uid="uid://bjah7k4bxo044"]
[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="Shader" path="res://src/ui_background.gdshader" id="4_ty3qx"]
[ext_resource type="Script" path="res://src/Editor.gd" id="7_g8bap"]
[ext_resource type="Script" path="res://src/Camera.gd" id="8_mls06"]
[sub_resource type="ViewportTexture" id="ViewportTexture_lct1c"]
viewport_path = NodePath("ImageViewport")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_onhxk"]
shader = ExtResource("4_ty3qx")
[node name="Main" type="Node2D"]
script = ExtResource("1_2625y")
[node name="ImageViewport" type="SubViewport" parent="."]
disable_3d = true
canvas_item_default_texture_filter = 0
render_target_update_mode = 4
script = ExtResource("2_hvo65")
[node name="ImageSprite" type="Sprite2D" parent="ImageViewport"]
[node name="ImageViewportDisplay" type="Sprite2D" parent="."]
texture = SubResource("ViewportTexture_lct1c")
script = ExtResource("3_n4itb")
[node name="UI_Layer" type="CanvasLayer" parent="."]
[node name="UserInterfaceContainer" type="Control" parent="UI_Layer"]
layout_mode = 3
anchor_right = 0.225
anchor_bottom = 1.0
offset_right = 288.0
grow_horizontal = 2
grow_vertical = 2
[node name="Background" type="ColorRect" parent="UI_Layer/UserInterfaceContainer"]
material = SubResource("ShaderMaterial_onhxk")
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
color = Color(1, 1, 1, 0)
[node name="OpenFileDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer"]
title = "Open a File"
size = Vector2i(521, 159)
ok_button_text = "Öffnen"
file_mode = 0
access = 2
use_native_dialog = true
[node name="SaveFileDialog" type="FileDialog" parent="UI_Layer/UserInterfaceContainer"]
title = "Export Image"
size = Vector2i(661, 159)
ok_button_text = "Speichern"
access = 2
filters = PackedStringArray("*.png")
use_native_dialog = true
[node name="OpenImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 0
offset_left = 24.0
offset_top = 24.0
offset_right = 136.0
offset_bottom = 56.0
text = "Load Image"
[node name="SaveImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 0
offset_left = 152.0
offset_top = 24.0
offset_right = 272.0
offset_bottom = 56.0
text = "Export Image"
[node name="FitImageButton" type="Button" parent="UI_Layer/UserInterfaceContainer"]
layout_mode = 0
offset_left = 288.0
offset_top = 24.0
offset_right = 376.0
offset_bottom = 56.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_right = -24.0
offset_bottom = -24.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("7_g8bap")
[node name="Label" type="Label" parent="UI_Layer/UserInterfaceContainer/Editor"]
layout_mode = 0
offset_top = 8.0
offset_right = 104.0
offset_bottom = 40.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_top = 8.0
offset_right = 240.0
offset_bottom = 32.0
[node name="CodeEdit" type="CodeEdit" parent="UI_Layer/UserInterfaceContainer/Editor"]
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="Camera" type="Camera2D" parent="."]
script = ExtResource("8_mls06")
[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/OpenFileDialog" to="." method="_on_open_file_dialog_file_selected"]
[connection signal="file_selected" from="UI_Layer/UserInterfaceContainer/SaveFileDialog" to="." method="_on_save_file_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="item_selected" from="UI_Layer/UserInterfaceContainer/Editor/PresetOptions" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_preset_options_item_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="text_changed" from="UI_Layer/UserInterfaceContainer/Editor/CodeEdit" to="UI_Layer/UserInterfaceContainer/Editor" method="_on_code_edit_text_changed"]

48
src/Camera.gd Normal file
View file

@ -0,0 +1,48 @@
extends Camera2D
var drag = false
var _freeze = false
@onready var user_interface_container = get_parent().get_node("UI_Layer/UserInterfaceContainer")
@onready var image_viewport = get_parent().get_node("ImageViewport")
func _input(event):
if event.is_action_pressed("zoom_out") && !_freeze:
zoom_out()
elif event.is_action_pressed("zoom_in") && !_freeze:
zoom_in()
if event.is_action_pressed("drag") && !_freeze:
drag = true
elif event.is_action_released("drag"):
drag = false
if drag && event is InputEventMouseMotion:
global_position -= event.relative / zoom
func fit_image():
var ui_container_size = user_interface_container.size
var image_size = image_viewport.image_original.get_size()
var viewport_size = get_viewport_rect().size
var zoomf = (viewport_size.x - ui_container_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(-((ui_container_size.x) / 2 / zoom.x), 0)
func zoom_in():
var old_mouse_pos = get_global_mouse_position()
zoom *= 1.2
global_position += old_mouse_pos - get_global_mouse_position()
func zoom_out():
var old_mouse_pos = get_global_mouse_position()
zoom *= 1/1.2
global_position += old_mouse_pos - get_global_mouse_position()
func freeze():
_freeze = true
func unfreeze():
_freeze = false
func _on_fit_image_button_pressed():
fit_image()

135
src/Editor.gd Normal file
View file

@ -0,0 +1,135 @@
extends Control
@onready var preset_options = $PresetOptions
@onready var code_editor = $CodeEdit
@onready var camera_freeze = get_parent().get_parent().get_parent().find_child("Camera").freeze
@onready var camera_unfreeze = get_parent().get_parent().get_parent().find_child("Camera").unfreeze
var selected_preset_name = ShaderPresets.default_preset
#
const gdshader_datatypes = [
"in", "out", "inout",
"varying", "uniform",
"const", "lowp", "mediump", "heighp",
"void",
"bool", "bvec2", "bvec3", "bvec4",
"int", "ivec2", "ivec3", "ivec4",
"uint", "uvec2", "uvec3", "uvec4",
"float", "vec2", "vec3", "vec4",
"mat2", "mat3", "mat4",
"sample2D", "isampler2D", "usample2D",
"sampler2DArray", "isample2DArray", "usample2DArray",
"sample3D", "isampler3D", "usample3D",
"samplerCube", "sampleCubeArray"
]
const gdshader_builtins = [
"TIME", "PI", "TAU", "E",
"MODEL_MATRIX",
"CANVAS_MATRIX",
"SCREEN_MATRIX",
"INSTANCE_ID",
"INSTANCE_CUSTOM",
"AT_LIGHT_PASS",
"TEXTURE_PIXEL_SIZE",
"VERTEX",
"VERTEX_ID",
"UV",
"COLOR",
"POINT_SIZE",
"FRAGCOORD",
"SCREEN_PIXEL_SIZE",
"POINT_COORD",
"TEXTURE",
"TEXTURE_PIXEL_SIZE",
"SPECULAR_SHININESS_TEXTURE",
"SPECULAR_SHININESS",
"UV",
"SCREEN_UV",
"SCREEN_TEXTURE",
"NORMAL",
"NORMAL_TEXTURE",
"NORMAL_MAP",
"NORMAL_MAP_DEPTH",
"SHADOW_VERTEX",
"LIGHT_VERTEX"
]
const gdshader_flow_control = [
"if", "else",
"for",
"do", "while",
"switch", "case",
"break",
"return"
]
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
keyword_colors = {
"shader_type": Color.ORCHID
}
for dt in gdshader_datatypes:
keyword_colors[dt] = Color.INDIAN_RED
for bi in gdshader_builtins:
keyword_colors[bi] = Color.DARK_TURQUOISE
for fc in gdshader_flow_control:
keyword_colors[fc] = Color.CORAL
member_variable_color = Color.LIGHT_BLUE
number_color = Color.AQUA
symbol_color = Color.GRAY
func _on_code_edit_code_completion_requested():
for dt in gdshader_datatypes:
code_editor.code_completion_prefixes.append(dt)
code_editor.add_code_completion_option(CodeEdit.KIND_CLASS, dt, dt, Color.INDIAN_RED)
for bi in gdshader_builtins:
code_editor.code_completion_prefixes.append(bi)
code_editor.add_code_completion_option(CodeEdit.KIND_VARIABLE, bi, bi, Color.DARK_TURQUOISE)
for fc in gdshader_flow_control:
code_editor.code_completion_prefixes.append(fc)
code_editor.add_code_completion_option(CodeEdit.KIND_PLAIN_TEXT, fc, fc, Color.DARK_TURQUOISE)
code_editor.update_code_completion_options(true)
#
func _ready():
code_editor.code_completion_enabled = true
code_editor.syntax_highlighter = ShaderSyntaxHighlighter.new()
for c in get_children():
c.connect("mouse_entered", camera_freeze)
c.connect("mouse_exited", camera_unfreeze)
update()
func _on_code_edit_text_changed():
var shader = Shader.new()
shader.code = code_editor.text
code_editor.request_code_completion()
GlitchShader.shader = shader
GlitchShader.apply()
func _on_preset_options_item_selected(index):
selected_preset_name = preset_options.get_item_text(index)
GlitchShader.shader = ShaderPresets.presets[selected_preset_name]
GlitchShader.apply()
update()
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 = GlitchShader.shader.code

10
src/GlitchShader.gd Normal file
View file

@ -0,0 +1,10 @@
extends Node
var target_sprite: Sprite2D
@onready var shader: Shader = ShaderPresets.presets[ShaderPresets.default_preset]
func apply():
var mat = ShaderMaterial.new()
mat.shader = shader
target_sprite.material = mat

11
src/ImageViewport.gd Normal file
View file

@ -0,0 +1,11 @@
extends SubViewport
@onready var image_sprite = $ImageSprite
var image_original: ImageTexture
func set_original_image(image: Image):
image_original = ImageTexture.create_from_image(image)
image_sprite.texture = image_original
image_sprite.offset = image_original.get_size() / 2
size = image_original.get_size()

View file

@ -0,0 +1,9 @@
extends Sprite2D
@onready var camera = get_parent().get_node("Camera")
func _process(_delta):
if camera.zoom.x >= 1.5:
texture_filter = TEXTURE_FILTER_NEAREST_WITH_MIPMAPS
else:
texture_filter = TEXTURE_FILTER_LINEAR

39
src/Main.gd Normal file
View file

@ -0,0 +1,39 @@
extends Node2D
@onready var camera = $Camera
@onready var image_viewport = $ImageViewport
@onready var image_sprite = $ImageViewport/ImageSprite
@onready var ui_container = $UI_Layer/UserInterfaceContainer
@onready var ui_control_fileopen = $UI_Layer/UserInterfaceContainer/OpenFileDialog
@onready var ui_control_filesave = $UI_Layer/UserInterfaceContainer/SaveFileDialog
func _ready():
GlitchShader.target_sprite = image_sprite
GlitchShader.shader = ShaderPresets.presets[ShaderPresets.default_preset]
func _on_open_image_button_pressed():
if OS.get_name() == "Android":
Engine.get_singleton("GodotGetImage").getGalleryImage()
else:
ui_control_fileopen.show()
func _on_open_file_dialog_file_selected(path):
var img = Image.new()
var err = img.load(path)
if err == OK:
image_viewport.set_original_image(img)
GlitchShader.apply()
camera.fit_image()
else:
print("An error occured!")
func _on_save_image_button_pressed():
ui_control_filesave.show()
func _on_save_file_dialog_file_selected(path):
# Get viewport texture
await RenderingServer.frame_post_draw # for good measure
var img = image_viewport.get_texture().get_image()
var err = img.save_png(path)
if err != OK:
print("An error occured!")

11
src/presets/Presets.gd Normal file
View file

@ -0,0 +1,11 @@
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")
}
var default_preset: String = "Empty"

View file

@ -0,0 +1,5 @@
shader_type canvas_item;
void fragment() {
// Called for every pixel the material is visible on.
}

View file

@ -0,0 +1,10 @@
shader_type canvas_item;
void fragment() {
// TODO: not only r
vec4 tex = texture(TEXTURE , UV);
COLOR.r = tex.r;
COLOR.g = tex.r;
COLOR.b = tex.r;
COLOR.a = tex.a;
}

View file

@ -0,0 +1,13 @@
shader_type canvas_item;
// Settings
const float threshold = 0.5;
//
void fragment() {
vec4 tex = texture(TEXTURE , UV);
COLOR.r = min(tex.r, threshold);
COLOR.g = min(tex.g, threshold);
COLOR.b = min(tex.b, threshold);
COLOR.a = tex.a;
}

View file

@ -0,0 +1,8 @@
shader_type canvas_item;
uniform sampler2D SCREEN_TEXTURE: hint_screen_texture, repeat_disable, filter_linear_mipmap_anisotropic;
void fragment() {
COLOR.rgb = clamp(textureLod(SCREEN_TEXTURE, SCREEN_UV, 10.0).rgb, 0.05, 0.7);
COLOR.a = 1.0;
}