diff --git a/includes/utils.h b/includes/utils.h index 320fab0..f31efee 100644 --- a/includes/utils.h +++ b/includes/utils.h @@ -36,4 +36,7 @@ void loadImg(const char *filename, const GLuint texture); // Copy a texture void copyTexture(const GLuint, const GLuint); +// Get the current FBO ID +GLuint getCurrentFramebufferID(void); + #endif diff --git a/shaders/credits.fs b/shaders/credits.fs index a7e8fd5..6939374 100644 --- a/shaders/credits.fs +++ b/shaders/credits.fs @@ -1,4 +1,5 @@ #version 330 + uniform sampler2D tex; in vec2 vsoTexCoord; out vec4 fragColor; diff --git a/shaders/manif.fs b/shaders/manif.fs index ee0e35b..634538a 100644 --- a/shaders/manif.fs +++ b/shaders/manif.fs @@ -2,6 +2,7 @@ in vec4 pos_model; in vec3 vec_normal; +in vec4 shadowMapCoord; out vec4 fragColor; @@ -11,6 +12,7 @@ uniform vec4 couleur; uniform vec4 lumPos[max]; uniform mat4 view; uniform vec4 lumColor[max]; +uniform sampler2D shadowmap; void main() { const vec3 vue = vec3(0, 0, -1); @@ -19,6 +21,12 @@ void main() { for(int i = 0; i < max; i++) { vec3 torche = normalize(pos_model.xyz - lumPos[i].xyz); float intensite_lumineuse = clamp(dot(vec_normal, -torche), 0., 1.); + + vec3 shadowMapPcoord = shadowMapCoord.xyz / shadowMapCoord.w; + if(texture(shadowmap, shadowMapPcoord.xy).r < shadowMapPcoord.z) { + intensite_lumineuse = 0; + } + vec3 reflet = (transpose(inverse(view)) * vec4(reflect(torche, vec_normal), 0)).xyz; float intensite_specularite = pow(clamp(dot(reflet, -vue), 0., 1.), 10); diff --git a/shaders/manif.vs b/shaders/manif.vs index 5488365..2ef7f49 100644 --- a/shaders/manif.vs +++ b/shaders/manif.vs @@ -5,12 +5,17 @@ layout(location = 1) in vec3 normal; out vec4 pos_model; out vec3 vec_normal; +out vec4 shadowMapCoord; uniform mat4 proj, model, view; +uniform mat4 lightView, lightProjection; void main() { + const mat4 bias = mat4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0); + pos_model = model * vec4(pos, 1); vec_normal = normalize(transpose(inverse(model)) * vec4(normal, 0)).xyz; + shadowMapCoord = bias * lightProjection * lightView * pos_model; gl_Position = proj * view * pos_model; } diff --git a/shaders/shadowMap.fs b/shaders/shadowMap.fs new file mode 100644 index 0000000..3060f41 --- /dev/null +++ b/shaders/shadowMap.fs @@ -0,0 +1,4 @@ +#version 330 + +void main(void) { +} diff --git a/shaders/shadowMap.vs b/shaders/shadowMap.vs new file mode 100644 index 0000000..ff00978 --- /dev/null +++ b/shaders/shadowMap.vs @@ -0,0 +1,12 @@ + +#version 330 + +uniform mat4 model; +uniform mat4 lightView; +uniform mat4 lightProjection; + +layout(location = 0) in vec3 vsiPosition; + +void main(void) { + gl_Position = lightProjection * lightView * model * vec4(vsiPosition, 1.0); +} diff --git a/src/animations.c b/src/animations.c index 04bd6d8..7c3cbe0 100644 --- a/src/animations.c +++ b/src/animations.c @@ -3,7 +3,8 @@ /* Mise-à-jour des animations en fonction du son */ static void update_with_audio(void (*)(int), void (*)(int), int); -static GLuint _transition_pId[2] = {0}, _transition_tId = 0, _quadId = 0; +static GLuint _transition_pId[2] = {0}, _transition_tId = 0, _quadId = 0, + _transition_fbo[2] = {0}; static void transition_init(const char *, const int, GLuint *); static void transition_draw(void (*)(int), void (*)(int), Uint32, Uint32, int, int, GLuint *); @@ -23,6 +24,7 @@ void transitionsInit(void) { if (!_quadId) { _quadId = gl4dgGenQuadf(); } + glGenFramebuffers(2, _transition_fbo); } void zoomIn(void (*a0)(int), void (*a1)(int), Uint32 t, Uint32 et, @@ -74,23 +76,29 @@ static void transition_draw(void (*a0)(int), void (*a1)(int), Uint32 t, glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint *)&_transition_tId); + GLint currentFramebufferID = getCurrentFramebufferID(); + glBindFramebuffer(GL_FRAMEBUFFER, _transition_fbo[0]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[0], 0); if (a0) { a0(state); } + glBindFramebuffer(GL_FRAMEBUFFER, _transition_fbo[1]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[1], 0); if (a1) { a1(state); } + glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _transition_tId, 0); glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex[0]); glActiveTexture(GL_TEXTURE1); @@ -113,7 +121,11 @@ static void transition_draw(void (*a0)(int), void (*a1)(int), Uint32 t, static void transition_deinit(GLuint *tex) { if (tex[0]) { glDeleteTextures(2, tex); - tex[0] = tex[1] = 0; + tex[0] = 0; + } + if (_transition_fbo[0]) { + glDeleteFramebuffers(2, _transition_fbo); + _transition_fbo[0] = 0; } } diff --git a/src/manif.c b/src/manif.c index 9653047..539bffb 100644 --- a/src/manif.c +++ b/src/manif.c @@ -1,17 +1,23 @@ #include "../includes/animations.h" -static GLuint _pId = 0; +static GLuint _pId[2] = {0}; static GLuint _planId = 0; #define HEROS_NUMBER 30 // should change in fragment shader too static struct manifestant _herosId[HEROS_NUMBER]; +#define SHADOW_MAP_SIDE 1024 +static GLuint _fbo = 0, _shadow_map_tex = 0; + static const char *matrix_proj = "proj"; static const char *matrix_model = "model"; static const char *matrix_view = "view"; +static const char *matrix_lview = "lightView"; +static const char *matrix_lproj = "lightProjection"; static void init(void); static void draw(void); +static void deinit(void); void manif(const int state) { switch (state) { @@ -23,6 +29,10 @@ void manif(const int state) { draw(); break; + case GL4DH_FREE: + deinit(); + break; + default: break; } @@ -39,27 +49,72 @@ static void init(void) { _herosId[i].ox = ((GLfloat)rand() / (GLfloat)RAND_MAX) * -50; _herosId[i].oz = 30 - ((GLfloat)rand() / (GLfloat)RAND_MAX) * 50; } - _pId = + _pId[0] = gl4duCreateProgram("shaders/manif.vs", "shaders/manif.fs", NULL); + _pId[1] = gl4duCreateProgram("shaders/shadowMap.vs", + "shaders/shadowMap.fs", NULL); + gl4duGenMatrix(GL_FLOAT, matrix_proj); gl4duGenMatrix(GL_FLOAT, matrix_model); gl4duGenMatrix(GL_FLOAT, matrix_view); + gl4duGenMatrix(GL_FLOAT, matrix_lview); + gl4duGenMatrix(GL_FLOAT, matrix_lproj); + + // Création et paramétrage de la Texture de shadow map + glGenTextures(1, &_shadow_map_tex); + glBindTexture(GL_TEXTURE_2D, _shadow_map_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_MAP_SIDE, + SHADOW_MAP_SIDE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + + // Création du FBO + glGenFramebuffers(1, &_fbo); } static void draw(void) { static double t0 = 0; double dt = get_dt(&t0, GL_TRUE); + static float deplacement = 0; glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); glClearColor(0.2f, 0.2f, 0.8f, 1); // couleur ciel + + glUseProgram(_pId[1]); + + bindAndLoadf(matrix_lproj); + gl4duLoadIdentityf(); + gl4duOrthof(-13, 13, -6, 6, 1, 40); + + bindAndLoadf(matrix_lview); + gl4duLookAtf(9, 6, 0, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); + glCullFace(GL_FRONT); + + GLint currentFramebufferID = getCurrentFramebufferID(); + + glBindFramebuffer(GL_FRAMEBUFFER, _fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + _shadow_map_tex, 0); + glViewport(0, 0, SHADOW_MAP_SIDE, SHADOW_MAP_SIDE); + glClear(GL_DEPTH_BUFFER_BIT); + for (int i = 0; i < HEROS_NUMBER; ++i) { + drawManifestant(matrix_model, &_herosId[i], deplacement, GL_TRUE); + } + glBindFramebuffer(GL_FRAMEBUFFER, currentFramebufferID); + + glCullFace(GL_BACK); + glDrawBuffer(GL_COLOR_ATTACHMENT0); + + glViewport(0, 0, _dims[0], _dims[1]); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glUseProgram(_pId); + glCullFace(GL_FRONT_FACE); + glUseProgram(_pId[0]); const GLfloat couleur_plan[] = {0.3f, 0.3f, 0.3f, 1}, couleur_heros[] = {1, 1, 0, 1}; - GLint couleur_gpu = glGetUniformLocation(_pId, "couleur"); - static float deplacement = 0; + GLint couleur_gpu = glGetUniformLocation(_pId[0], "couleur"); bindAndLoadf(matrix_proj); GLfloat ratio = (GLfloat)_dims[0] / (GLfloat)_dims[1]; @@ -96,11 +151,26 @@ static void draw(void) { drawManifestant(matrix_model, &_herosId[i], deplacement, GL_TRUE); } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _shadow_map_tex); int max_gpu = 3; // HEROS_NUMBER; - glUniform4fv(glGetUniformLocation(_pId, "lumPos"), max_gpu, (float *)lumpos); - glUniform4fv(glGetUniformLocation(_pId, "lumColor"), max_gpu, + glUniform4fv(glGetUniformLocation(_pId[0], "lumPos"), max_gpu, + (float *)lumpos); + glUniform4fv(glGetUniformLocation(_pId[0], "lumColor"), max_gpu, (float *)lumcolor); + glUniform1i(glGetUniformLocation(_pId[0], "shadowmap"), 0); deplacement += (float)(0.4 * M_PI * dt); glUseProgram(0); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); +} + +static void deinit(void) { + if (_fbo) { + glDeleteTextures(1, &_shadow_map_tex); + glDeleteFramebuffers(1, &_fbo); + _fbo = 0; + } } diff --git a/src/tag.c b/src/tag.c index 1032510..ff61d9c 100644 --- a/src/tag.c +++ b/src/tag.c @@ -104,6 +104,7 @@ static void draw(void) { glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_DEPTH_TEST); } static void deinit(void) { diff --git a/src/utils.c b/src/utils.c index 58c3245..f8535fe 100644 --- a/src/utils.c +++ b/src/utils.c @@ -88,3 +88,10 @@ void copyTexture(const GLuint src, const GLuint dst) { SDL_FreeSurface(s); glBindTexture(GL_TEXTURE_2D, 0); } + +GLuint getCurrentFramebufferID(void) { + GLint currentFramebufferID = 0; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFramebufferID); + + return currentFramebufferID; +}