From a2b6cbe0c38155ddcce0b99d1c65b1fe5cd02666 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 15 May 2022 20:25:16 +0200 Subject: [PATCH] Add transition between 2 scene of a rotating cube --- includes/animations.h | 13 +++++-- shaders/cube.fs | 10 ++++++ shaders/cube.vs | 23 +++++++++++++ shaders/fondu.fs | 12 +++++++ shaders/fondu.vs | 12 +++++++ src/animations.c | 5 --- src/cube.c | 74 ++++++++++++++++++++++++++++++++++++++++ src/cube2.c | 74 ++++++++++++++++++++++++++++++++++++++++ src/fondu.c | 79 +++++++++++++++++++++++++++++++++++++++++++ window.c | 17 ++++------ 10 files changed, 301 insertions(+), 18 deletions(-) create mode 100644 shaders/cube.fs create mode 100644 shaders/cube.vs create mode 100644 shaders/fondu.fs create mode 100644 shaders/fondu.vs delete mode 100644 src/animations.c create mode 100644 src/cube.c create mode 100644 src/cube2.c create mode 100644 src/fondu.c diff --git a/includes/animations.h b/includes/animations.h index e284405..a2c22f1 100644 --- a/includes/animations.h +++ b/includes/animations.h @@ -3,7 +3,16 @@ #include -// Comportement avant de lancer les animations -void initialisationAnimation(void); +// Dimensions initiales de la fenêtre +extern int dimensions[]; + +// Cube coloré qui tourne sur lui-même +void cube(int); + +// Cube2 coloré qui tourne sur lui-même +void cube2(int); + +// Effet de transition en fondu +void fondu(void (*)(int), void (*)(int), Uint32, Uint32, int); #endif diff --git a/shaders/cube.fs b/shaders/cube.fs new file mode 100644 index 0000000..2a430a3 --- /dev/null +++ b/shaders/cube.fs @@ -0,0 +1,10 @@ +#version 330 + +in vec4 vsoColor; +out vec4 maSortie; + +in float il; + +void main() { + maSortie = il * vsoColor; +} diff --git a/shaders/cube.vs b/shaders/cube.vs new file mode 100644 index 0000000..b31e053 --- /dev/null +++ b/shaders/cube.vs @@ -0,0 +1,23 @@ +#version 330 + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; +layout(location = 2) in vec2 texCoord; + +uniform mat4 proj; +uniform mat4 modview; +uniform mat4 view; + +out vec4 vsoColor; +out float il; +const vec3 Ld = vec3(0., -.707, -.707); + + +void main() { + vec3 n = (transpose(inverse(modview)) * vec4(normal, 0.0)).xyz; + il = clamp(dot(n, -Ld), 0.0, 1.0); + + gl_Position = proj * view * modview * vec4(position, 1.); + + vsoColor = vec4(texCoord, 0.5, 1); +} diff --git a/shaders/fondu.fs b/shaders/fondu.fs new file mode 100644 index 0000000..dcffecf --- /dev/null +++ b/shaders/fondu.fs @@ -0,0 +1,12 @@ +#version 330 + +uniform float delta_temps; +uniform sampler2D tex0; +uniform sampler2D tex1; + +in vec2 vsoTexCoord; +out vec4 fragColor; + +void main(void) { + fragColor = mix(texture(tex0, vsoTexCoord), texture(tex1, vsoTexCoord), delta_temps); +} diff --git a/shaders/fondu.vs b/shaders/fondu.vs new file mode 100644 index 0000000..2472da9 --- /dev/null +++ b/shaders/fondu.vs @@ -0,0 +1,12 @@ +#version 330 + +layout (location = 0) in vec3 vsiPosition; +layout (location = 1) in vec3 vsiNormal; +layout (location = 2) in vec2 vsiTexCoord; + +out vec2 vsoTexCoord; + +void main(void) { + gl_Position = vec4(vsiPosition, 1.0); + vsoTexCoord = vec2(vsiTexCoord.s, vsiTexCoord.t); +} diff --git a/src/animations.c b/src/animations.c deleted file mode 100644 index b0c8ed6..0000000 --- a/src/animations.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "../includes/animations.h" - -void initialisationAnimation(void) { - /* ... */ -} diff --git a/src/cube.c b/src/cube.c new file mode 100644 index 0000000..818531e --- /dev/null +++ b/src/cube.c @@ -0,0 +1,74 @@ +#include "../includes/animations.h" + +void cube(int etat) { + static GLuint cube = 0, proc_id = 0; + + static GLclampf r = 0, + g = 0, + b = 0; + + switch(etat) { + case GL4DH_INIT: + r = (rand() / (float)(RAND_MAX)) * 1.f; + g = (rand() / (float)(RAND_MAX)) * 1.f; + b = (rand() / (float)(RAND_MAX)) * 1.f; + + cube = gl4dgGenCubef(); + proc_id = gl4duCreateProgram("shaders/cube.vs", "shaders/cube.fs", NULL); + + gl4duGenMatrix(GL_FLOAT, "modview"); + gl4duGenMatrix(GL_FLOAT, "view"); + gl4duGenMatrix(GL_FLOAT, "proj"); + + gl4duBindMatrix("proj"); + + gl4duLoadIdentityf(); + + gl4duFrustumf(-1, 1, -1, 1, 1, 1000); + + // resize + GLfloat ratio_inverse; + GLuint fenetre_largeur = dimensions[0], fenetre_hauteur = dimensions[1]; + glViewport(0, 0, fenetre_largeur, fenetre_hauteur); + ratio_inverse = fenetre_hauteur / (GLfloat)fenetre_largeur; + gl4duBindMatrix("proj"); + gl4duLoadIdentityf(); + gl4duFrustumf(-1.f, 1.f, -1.f * ratio_inverse, 1.f * ratio_inverse, 1.f, 1000.f); + + glEnable(GL_DEPTH_TEST); + break; + + case GL4DH_UPDATE_WITH_AUDIO: + break; + + case GL4DH_DRAW: + glClearColor(r, g, b, 1.f); + static GLfloat cube_rotation = 0; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(proc_id); + + gl4duBindMatrix("view"); + gl4duLoadIdentityf(); + gl4duLookAtf(0, 0, 5, 0, 0, 0, 0, 1, 0); + + gl4duBindMatrix("modview"); + gl4duLoadIdentityf(); + + gl4duPushMatrix(); + gl4duRotatef(cube_rotation, 0, 1, 0); + gl4duSendMatrices(); + gl4dgDraw(cube); + gl4duPopMatrix(); + + glUseProgram(0); + + ++cube_rotation; + break; + + case GL4DH_FREE: + break; + + default: + break; + } +} diff --git a/src/cube2.c b/src/cube2.c new file mode 100644 index 0000000..b057fc1 --- /dev/null +++ b/src/cube2.c @@ -0,0 +1,74 @@ +#include "../includes/animations.h" + +void cube2(int etat) { + static GLuint cube = 0, proc_id = 0; + + static GLclampf r = 0, + g = 0, + b = 0; + + switch(etat) { + case GL4DH_INIT: + r = (rand() / (float)(RAND_MAX)) * 1.f; + g = (rand() / (float)(RAND_MAX)) * 1.f; + b = (rand() / (float)(RAND_MAX)) * 1.f; + + cube = gl4dgGenCubef(); + proc_id = gl4duCreateProgram("shaders/cube.vs", "shaders/cube.fs", NULL); + + gl4duGenMatrix(GL_FLOAT, "modview"); + gl4duGenMatrix(GL_FLOAT, "view"); + gl4duGenMatrix(GL_FLOAT, "proj"); + + gl4duBindMatrix("proj"); + + gl4duLoadIdentityf(); + + gl4duFrustumf(-1, 1, -1, 1, 1, 1000); + + // resize + GLfloat ratio_inverse; + GLuint fenetre_largeur = dimensions[0], fenetre_hauteur = dimensions[1]; + glViewport(0, 0, fenetre_largeur, fenetre_hauteur); + ratio_inverse = fenetre_hauteur / (GLfloat)fenetre_largeur; + gl4duBindMatrix("proj"); + gl4duLoadIdentityf(); + gl4duFrustumf(-1.f, 1.f, -1.f * ratio_inverse, 1.f * ratio_inverse, 1.f, 1000.f); + + glEnable(GL_DEPTH_TEST); + break; + + case GL4DH_UPDATE_WITH_AUDIO: + break; + + case GL4DH_DRAW: + glClearColor(r, g, b, 1.f); + static GLfloat cube_rotation = 0; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(proc_id); + + gl4duBindMatrix("view"); + gl4duLoadIdentityf(); + gl4duLookAtf(0, 0, 5, 0, 0, 0, 0, 1, 0); + + gl4duBindMatrix("modview"); + gl4duLoadIdentityf(); + + gl4duPushMatrix(); + gl4duRotatef(cube_rotation, 0, 1, 0); + gl4duSendMatrices(); + gl4dgDraw(cube); + gl4duPopMatrix(); + + glUseProgram(0); + + ++cube_rotation; + break; + + case GL4DH_FREE: + break; + + default: + break; + } +} diff --git a/src/fondu.c b/src/fondu.c new file mode 100644 index 0000000..32c1db7 --- /dev/null +++ b/src/fondu.c @@ -0,0 +1,79 @@ +#include "../includes/animations.h" + +/* Fondu de Farès BELHADJ */ + +void fondu(void (* ancienne_anim)(int), void (* nouvelle_anim)(int), Uint32 temps_total, Uint32 temps_ecoule, int etat) { + GLint viewport[4]; + GLint tex_id = 0; + static GLuint ecran[2], proc_id = 0, quad = 0; + + switch(etat) { + case GL4DH_INIT: + quad = gl4dgGenQuadf(); + + glGetIntegerv(GL_VIEWPORT, viewport); + + glGenTextures(2, ecran); + for(int i = 0; i < 2; ++i) { + glBindTexture(GL_TEXTURE_2D, ecran[i]); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewport[2], viewport[3], 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + + proc_id = gl4duCreateProgram("shaders/fondu.vs", "shaders/fondu.fs", NULL); + break; + + case GL4DH_UPDATE_WITH_AUDIO: + break; + + case GL4DH_DRAW: + // Récupération ID texture + glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tex_id); + + // Dessine les deux animations + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ecran[0], 0); + if(ancienne_anim) { + ancienne_anim(etat); + } + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ecran[1], 0); + if(nouvelle_anim) { + nouvelle_anim(etat); + } + + // Mix des deux écrans + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0); + glDisable(GL_DEPTH); + glUseProgram(proc_id); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ecran[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, ecran[1]); + + glUniform1f(glGetUniformLocation(proc_id, "delta_temps"), temps_ecoule / (GLfloat)temps_total); + glUniform1i(glGetUniformLocation(proc_id, "tex0"), 0); + glUniform1i(glGetUniformLocation(proc_id, "tex1"), 1); + gl4dgDraw(quad); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + break; + + case GL4DH_FREE: + if(ecran[0] || ecran[1]) { + glDeleteTextures(2, ecran); + ecran[0] = ecran[1] = 0; + } + break; + + default: + break; + } +} diff --git a/window.c b/window.c index 2cd5937..f2286d1 100644 --- a/window.c +++ b/window.c @@ -2,25 +2,24 @@ #include "includes/animations.h" -// Dimensions initiales de la fenêtre -static int dimensions[] = {1280, 720}; +int dimensions[] = {1280, 720}; // Animations static GL4DHanime animations[] = { - {0, NULL, NULL, NULL} + { 5000, cube, NULL, NULL }, + { 2500, cube, cube2, fondu }, + { 5000, cube2, NULL, NULL }, + { 0, NULL, NULL, NULL } }; // Comportement à la fermeture du programme static void fermeture(void); -// Comportement au démarrage du programme -void initialisation(void); - int main(int argc, char *argv[]) { if(!gl4duwCreateWindow(argc, argv, "Démo Anri KENNEL", 10, 10, dimensions[0], dimensions[1], GL4DW_SHOWN)) { return 1; } - initialisation(); + gl4dhInit(animations, dimensions[0], dimensions[1], NULL); atexit(fermeture); gl4duwDisplayFunc(gl4dhDraw); @@ -29,10 +28,6 @@ int main(int argc, char *argv[]) { return 0; } -void initialisation(void) { - gl4dhInit(animations, dimensions[0], dimensions[1], initialisationAnimation); -} - void fermeture(void) { gl4duClean(GL4DU_ALL); }