diff --git a/examples/exemple_maximekervran/GDScript.gd b/examples/exemple_maximekervran/GDScript.gd new file mode 100644 index 0000000..3112d9c --- /dev/null +++ b/examples/exemple_maximekervran/GDScript.gd @@ -0,0 +1,42 @@ +extends Node + +# Référence au ComputeShader +var compute_shader + +# Structure pour les paramètres à passer au shader +var params = { + "mouse_clicked": false, + "mouse_position": Vector2(0, 0) +} + +func _ready(): + # Récupérer le ComputeShader (ajustez le chemin selon votre structure) + compute_shader = $/ProjetMaximeKERVRAN/ComputeShaderStudio2D + + # Initialiser les paramètres du shader + update_shader_params() + +func _input(event): + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_LEFT and event.pressed: + # Mettre à jour les paramètres quand le bouton gauche est cliqué + params.mouse_clicked = true + params.mouse_position = event.position + update_shader_params() + elif event.button_index == MOUSE_BUTTON_LEFT and not event.pressed: + # Réinitialiser si on relâche le bouton + params.mouse_clicked = false + update_shader_params() + + if event is InputEventMouseMotion and Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT): + # Mettre à jour la position pendant que le bouton est enfoncé (optionnel) + params.mouse_position = event.position + update_shader_params() + +func update_shader_params(): + # Passer les paramètres au shader + compute_shader.set_shader_parameter("mouse_clicked", params.mouse_clicked) + compute_shader.set_shader_parameter("mouse_position", params.mouse_position) + + # Déclencher le calcul du shader + compute_shader.dispatch() diff --git a/examples/exemple_maximekervran/node_2d.gdshader b/examples/exemple_maximekervran/node_2d.gdshader new file mode 100644 index 0000000..e0f43bd --- /dev/null +++ b/examples/exemple_maximekervran/node_2d.gdshader @@ -0,0 +1,22 @@ +shader_type canvas_item; + +void fragment() { + // Centrer les UV (elles vont de 0 à 1 → on les centre à 0) + vec2 uv = UV - vec2(0.5); + + // Calcul de la distance au centre + float dist = length(uv); + + // Rayon du cercle : 0.5 = tout le Sprite + if (dist > 0.5) { + discard; // On efface tout ce qui est hors du cercle + } + + // Couleur jaune dorée + COLOR = vec4(1.0, 0.84, 0.0, 1.0); // or +} + +//void light() { + // Called for every pixel for every light affecting the CanvasItem. + // Uncomment to replace the default light processing function with this one. +//} diff --git a/examples/exemple_maximekervran/node_2d.tscn b/examples/exemple_maximekervran/node_2d.tscn new file mode 100644 index 0000000..34eba53 --- /dev/null +++ b/examples/exemple_maximekervran/node_2d.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=3 uid="uid://bbx6m03cjregi"] + +[ext_resource type="Script" path="res://Projet_shader/GDScript.gd" id="1_ncx3q"] +[ext_resource type="Texture2D" uid="uid://cuxtavxidco0j" path="res://icon.svg" id="2_v8pp1"] + +[node name="ProjetMaximeKERVRAN" type="Node2D"] +position = Vector2(369, 112) + +[node name="ComputeShaderStudio2D" type="Node" parent="."] +script = ExtResource("1_ncx3q") + +[node name="Icon" type="Sprite2D" parent="."] +position = Vector2(121, 158.906) +scale = Vector2(-3.09465, 2.81873) +texture = ExtResource("2_v8pp1") diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp new file mode 100644 index 0000000..5163ff5 --- /dev/null +++ b/examples/exemple_maximekervran/shader.cpp @@ -0,0 +1,104 @@ +#define FOND 0x00000000 +#define RAYON 50.0 +#define PI 3.141592 + +//calc cercle euclidien +void cercle(uint cy, uint cx, int couleur) { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + float distance = sqrt(float((x - cx) * (x - cx) + (y - cy) * (y - cy))); + + if (distance <= RAYON) { + data_0[p] = couleur; + } else { + data_0[p] = FOND; + } +} + +//cycle de couleurs +int couleur_rebond(int rebonds) { + if (rebonds % 6 == 0) return 0xFFFFFFFF; // Blanc + if (rebonds % 6 == 1) return 0xFF0000FF; // Rouge + if (rebonds % 6 == 2) return 0xFF00FF00; // Vert + if (rebonds % 6 == 3) return 0xFFFF0000; // Bleu + if (rebonds % 6 == 4) return 0xFF00FFFF; // Jaune + return 0xFFFF00FF; // Magenta +} + +void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + //nettoyage + data_0[p] = FOND; + + //pos souris + uint mouse_x = uint(mousex); + uint mouse_y = uint(mousey); + + //etat bouton souris + bool mouse_pressed = mouse_button > 0; + + //stocke coordonnees de lancement + bool depart_balle = (data_1[0] == 1); + uint depart_x = uint(data_1[1]); + uint depart_y = uint(data_1[2]); + uint depart_step = uint(data_1[3]); + + //gestion lancement balle + if (mouse_pressed && (!depart_balle || (mouse_x != depart_x || mouse_y != depart_y))) { + //stocke animation + data_1[0] = 1; + + //Enregistre lancement + data_1[1] = int(mouse_x); + data_1[2] = int(mouse_y); + data_1[3] = int(step); + + //Maj var locales + depart_balle = true; + depart_x = mouse_x; + depart_y = mouse_y; + depart_step = uint(step); + } + + + //calc position + if (depart_balle) { + float temps_ecoule = float(step - depart_step); + float maxHauteur = float(depart_y); + float minHauteur = float(WSY - uint(RAYON)); + float tempsRebond = 90.0; + float energiePerdue = 0.85; + + + float pos_y; + int nbRebonds = 0; + + //calc temps ecoule + if (temps_ecoule < tempsRebond) { + //premier rebond + float normalized_time = temps_ecoule / tempsRebond;//entre 0 et 1 + pos_y = maxHauteur + (minHauteur - maxHauteur) * normalized_time * normalized_time; + if (pos_y > minHauteur) { + pos_y = minHauteur; + } + } else { + //rebonds suivants + float cycles = temps_ecoule / tempsRebond; + nbRebonds = int(floor(cycles)); + float amplitude = (minHauteur - maxHauteur) * pow(energiePerdue, float(nbRebonds)); + float phase = (cycles - floor(cycles)) * 2.0 * PI; + pos_y = minHauteur - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); + } + + //couleur balle + int couleur_actuelle = couleur_rebond(nbRebonds); + + //Dessin balle + cercle(uint(pos_y) - WSY/6, depart_x + WSX/2, couleur_actuelle); + } +}