From fe433d99dcc74f1e8b0174bb153bc79e699507c6 Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Wed, 5 Mar 2025 09:41:40 +0100 Subject: [PATCH 1/7] Create shader.cpp --- examples/exemple_maximekervran/shader.cpp | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/exemple_maximekervran/shader.cpp diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/exemple_maximekervran/shader.cpp @@ -0,0 +1 @@ + From 8a09cf5e781de3ca77055b99c16ea5b398205a0c Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Thu, 13 Mar 2025 15:39:20 +0100 Subject: [PATCH 2/7] premier commit --- examples/exemple_maximekervran/GDScript.gd | 42 ++++++++++++++ .../exemple_maximekervran/node_2d.gdshader | 22 ++++++++ examples/exemple_maximekervran/node_2d.tscn | 15 +++++ examples/exemple_maximekervran/shader.cpp | 55 +++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 examples/exemple_maximekervran/GDScript.gd create mode 100644 examples/exemple_maximekervran/node_2d.gdshader create mode 100644 examples/exemple_maximekervran/node_2d.tscn 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 index 8b13789..d157eaa 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -1 +1,56 @@ +#define CERCLE 0xFFFFFFFF +#define FOND 0x00000000 +#define RAYON 100.0 +#define PI 3.141592 + +// Uniforme qui sera passé depuis le script GDScript +layout(set = 0, binding = 0) uniform Params { + bool mouse_clicked; + vec2 mouse_position; +}; + + +void cercle(uint cy, uint cx){ + 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] = CERCLE; // Pixel blanc + } else { + data_0[p] = FOND; // Pixel noir (fond) + } +} + +void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + + data_0[p] = FOND; + + if (mouse_clicked) { + cercle(uint(mouse_position.y), uint(mouse_position.x)); + } +} + + +/*void main() { + uint x = gl_GlobalInvocationID.x; + uint y = gl_GlobalInvocationID.y; + uint p = x + y * WSX; + int opacity = 0xFF000000 ; + int blue = 0x550000; + int green = 0x3300; + int red = int(y*2) ; + data_0[p] = opacity+blue+green+red; +}*/ + + +/*void button() + var btn : int = 1; + input.param.append(Input.get_mouse_button_mask())//renvoie 1 si bouton gauche cliqué +if(Input.is_mouse_button_pssed(Mouse_button_left))*/ \ No newline at end of file From 84f0d295fbe94d1f60574887bba6a9dfaceb819e Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Sun, 16 Mar 2025 15:56:23 +0100 Subject: [PATCH 3/7] =?UTF-8?q?balle=20qui=20appara=C3=AEt=20au=20m=C3=AAm?= =?UTF-8?q?e=20endroit=20et=20rebondit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/exemple_maximekervran/shader.cpp | 84 +++++++++++++---------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp index d157eaa..70b73d4 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -1,56 +1,68 @@ -#define CERCLE 0xFFFFFFFF -#define FOND 0x00000000 -#define RAYON 100.0 +#define CERCLE 0xFFFFFFFF +#define FOND 0x00000000 +#define RAYON 50.0 #define PI 3.141592 - -// Uniforme qui sera passé depuis le script GDScript -layout(set = 0, binding = 0) uniform Params { - bool mouse_clicked; - vec2 mouse_position; -}; - - -void cercle(uint cy, uint cx){ +void cercle(uint cy, uint cx) { uint x = gl_GlobalInvocationID.x; - uint y = gl_GlobalInvocationID.y; + 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] = CERCLE; // Pixel blanc + data_0[p] = CERCLE; // White pixel } else { - data_0[p] = FOND; // Pixel noir (fond) + data_0[p] = FOND; // Black pixel (background) } } void main() { uint x = gl_GlobalInvocationID.x; - uint y = gl_GlobalInvocationID.y; + uint y = gl_GlobalInvocationID.y; uint p = x + y * WSX; + // Clear screen data_0[p] = FOND; - if (mouse_clicked) { - cercle(uint(mouse_position.y), uint(mouse_position.x)); + // Ball position + uint ball_x = 250; + + // Calculate y position with bounce effect + float time = float(step); + float gravity = 0.5; + float topHeight = 50.0; + float bottomHeight = float(WSY - uint(RAYON)); + + // Simple bounce calculation + float bounce_period = 90.0; // Time for one complete bounce cycle + float bounce_decay = 0.85; // How much energy is lost per bounce + + // Calculate based on sine wave with decreasing amplitude + float cycles = time / bounce_period; + float amplitude = (bottomHeight - topHeight) * pow(bounce_decay, floor(cycles)); + float phase = (cycles - floor(cycles)) * 2.0 * PI; + + // Position calculation: start at bottom, bounce up with decreasing height + //float y_pos = maxHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); + + // Position calculation: start at top, fall down to bottom, then bounce + float y_pos; +// For the first cycle, use a simple gravity equation to make it fall naturally + if (cycles < 1.0) { + // Simple gravity equation: y = y0 + v0*t + 0.5*g*t² + float normalized_time = cycles; // Between 0 and 1 + y_pos = topHeight + (bottomHeight - topHeight) * normalized_time * normalized_time; + + // Ensure it doesn't go past the bottom + if (y_pos > bottomHeight) { + y_pos = bottomHeight; + } + } else { + // After first impact, use the sine wave for bouncing + y_pos = bottomHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); } -} - - -/*void main() { - uint x = gl_GlobalInvocationID.x; - uint y = gl_GlobalInvocationID.y; - uint p = x + y * WSX; - int opacity = 0xFF000000 ; - int blue = 0x550000; - int green = 0x3300; - int red = int(y*2) ; - data_0[p] = opacity+blue+green+red; -}*/ - -/*void button() - var btn : int = 1; - input.param.append(Input.get_mouse_button_mask())//renvoie 1 si bouton gauche cliqué -if(Input.is_mouse_button_pssed(Mouse_button_left))*/ \ No newline at end of file + // Draw the ball + cercle(uint(y_pos), ball_x); +} \ No newline at end of file From 88c69df7e281e4eec0728fdfb55a5df5e5c1b147 Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Mon, 17 Mar 2025 10:02:54 +0100 Subject: [PATCH 4/7] =?UTF-8?q?la=20balle=20rebondit=20l=C3=A0=20o=C3=B9?= =?UTF-8?q?=20on=20clique=20et=20recommence=20=C3=A0=20rebondir=20=C3=A0?= =?UTF-8?q?=20partir=20du=20point=20mais=20pas=20tout=20=C3=A0=20fait=20?= =?UTF-8?q?=C3=A0=20l'endroit=20du=20clic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/exemple_maximekervran/shader.cpp | 97 ++++++++++++++--------- 1 file changed, 58 insertions(+), 39 deletions(-) diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp index 70b73d4..261ee8b 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -11,9 +11,9 @@ void cercle(uint cy, uint cx) { float distance = sqrt(float((x - cx) * (x - cx) + (y - cy) * (y - cy))); if (distance <= RAYON) { - data_0[p] = CERCLE; // White pixel + data_0[p] = CERCLE; } else { - data_0[p] = FOND; // Black pixel (background) + data_0[p] = FOND; } } @@ -22,47 +22,66 @@ void main() { uint y = gl_GlobalInvocationID.y; uint p = x + y * WSX; - // Clear screen + //nettoyage data_0[p] = FOND; - // Ball position - uint ball_x = 250; - - // Calculate y position with bounce effect - float time = float(step); - float gravity = 0.5; - float topHeight = 50.0; - float bottomHeight = float(WSY - uint(RAYON)); - - // Simple bounce calculation - float bounce_period = 90.0; // Time for one complete bounce cycle - float bounce_decay = 0.85; // How much energy is lost per bounce - - // Calculate based on sine wave with decreasing amplitude - float cycles = time / bounce_period; - float amplitude = (bottomHeight - topHeight) * pow(bounce_decay, floor(cycles)); - float phase = (cycles - floor(cycles)) * 2.0 * PI; + //pos souris + uint mouse_x = uint(mousex); + uint mouse_y = uint(mousey); + + //etat 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]); + + if (mouse_pressed && (!depart_balle || (mouse_x != depart_x || mouse_y != depart_y))) { + //etat lance + 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); + } - // Position calculation: start at bottom, bounce up with decreasing height - //float y_pos = maxHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); - // Position calculation: start at top, fall down to bottom, then bounce - float y_pos; -// For the first cycle, use a simple gravity equation to make it fall naturally - if (cycles < 1.0) { - // Simple gravity equation: y = y0 + v0*t + 0.5*g*t² - float normalized_time = cycles; // Between 0 and 1 - y_pos = topHeight + (bottomHeight - topHeight) * normalized_time * normalized_time; + //calc pos + 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; + + // Position calculation: start at bottom, bounce up with decreasing height + //float y_pos = maxHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); - // Ensure it doesn't go past the bottom - if (y_pos > bottomHeight) { - y_pos = bottomHeight; + + float pos_y; + if (temps_ecoule < 1.0) { + 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 { + float cycles = temps_ecoule / tempsRebond; + float amplitude = (minHauteur - maxHauteur) * pow(energiePerdue, floor(cycles)); + float phase = (cycles - floor(cycles)) * 2.0 * PI; + pos_y = minHauteur - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); } - } else { - // After first impact, use the sine wave for bouncing - y_pos = bottomHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); - } - // Draw the ball - cercle(uint(y_pos), ball_x); -} \ No newline at end of file + //Dessin balle + cercle(uint(pos_y), depart_x); + } +} From 72f85fc39035e50211cf40f951a81383335e6b9f Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Mon, 17 Mar 2025 19:17:59 +0100 Subject: [PATCH 5/7] la balle part de la souris et rebondit --- examples/exemple_maximekervran/shader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp index 261ee8b..1d87f31 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -68,7 +68,7 @@ void main() { float pos_y; - if (temps_ecoule < 1.0) { + if (temps_ecoule < tempsRebond) { float normalized_time = temps_ecoule / tempsRebond;//entre 0 et 1 pos_y = maxHauteur + (minHauteur - maxHauteur) * normalized_time * normalized_time; if (pos_y > minHauteur) { @@ -82,6 +82,6 @@ void main() { } //Dessin balle - cercle(uint(pos_y), depart_x); + cercle(uint(pos_y) - WSY/6, depart_x + WSX/2); } } From 0158b839edd95beab0222488c82d1e161c8ece66 Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Mon, 17 Mar 2025 20:24:29 +0100 Subject: [PATCH 6/7] balle qui change de couleur aux rebonds --- examples/exemple_maximekervran/shader.cpp | 25 ++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp index 1d87f31..c904b71 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -1,9 +1,10 @@ -#define CERCLE 0xFFFFFFFF #define FOND 0x00000000 #define RAYON 50.0 #define PI 3.141592 -void cercle(uint cy, uint cx) { + + +void cercle(uint cy, uint cx, int couleur) { uint x = gl_GlobalInvocationID.x; uint y = gl_GlobalInvocationID.y; uint p = x + y * WSX; @@ -11,12 +12,21 @@ void cercle(uint cy, uint cx) { float distance = sqrt(float((x - cx) * (x - cx) + (y - cy) * (y - cy))); if (distance <= RAYON) { - data_0[p] = CERCLE; + data_0[p] = couleur; } else { data_0[p] = FOND; } } +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; @@ -68,6 +78,8 @@ void main() { float pos_y; + int nbRebonds = 0; + if (temps_ecoule < tempsRebond) { float normalized_time = temps_ecoule / tempsRebond;//entre 0 et 1 pos_y = maxHauteur + (minHauteur - maxHauteur) * normalized_time * normalized_time; @@ -76,12 +88,15 @@ void main() { } } else { float cycles = temps_ecoule / tempsRebond; - float amplitude = (minHauteur - maxHauteur) * pow(energiePerdue, floor(cycles)); + 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)); } + int couleur_actuelle = couleur_rebond(nbRebonds); + //Dessin balle - cercle(uint(pos_y) - WSY/6, depart_x + WSX/2); + cercle(uint(pos_y) - WSY/6, depart_x + WSX/2, couleur_actuelle); } } From bd180f030186e4104327d245bdfe77d5239c6e62 Mon Sep 17 00:00:00 2001 From: maximeKervran <157500888+maximeKervran@users.noreply.github.com> Date: Mon, 17 Mar 2025 22:28:13 +0100 Subject: [PATCH 7/7] code propre --- examples/exemple_maximekervran/shader.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/examples/exemple_maximekervran/shader.cpp b/examples/exemple_maximekervran/shader.cpp index c904b71..5163ff5 100644 --- a/examples/exemple_maximekervran/shader.cpp +++ b/examples/exemple_maximekervran/shader.cpp @@ -2,8 +2,7 @@ #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; @@ -18,6 +17,7 @@ void cercle(uint cy, uint cx, int couleur) { } } +//cycle de couleurs int couleur_rebond(int rebonds) { if (rebonds % 6 == 0) return 0xFFFFFFFF; // Blanc if (rebonds % 6 == 1) return 0xFF0000FF; // Rouge @@ -39,7 +39,7 @@ void main() { uint mouse_x = uint(mousex); uint mouse_y = uint(mousey); - //etat souris + //etat bouton souris bool mouse_pressed = mouse_button > 0; //stocke coordonnees de lancement @@ -48,8 +48,9 @@ void main() { 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))) { - //etat lance + //stocke animation data_1[0] = 1; //Enregistre lancement @@ -65,28 +66,28 @@ void main() { } - //calc pos + //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; - - // Position calculation: start at bottom, bounce up with decreasing height - //float y_pos = maxHeight - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); - + 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)); @@ -94,6 +95,7 @@ void main() { pos_y = minHauteur - amplitude * (0.5 + 0.5 * sin(phase - PI/2.0)); } + //couleur balle int couleur_actuelle = couleur_rebond(nbRebonds); //Dessin balle