diff --git a/shaders/manif.fs b/shaders/manif.fs index ee0e35b..7e2804e 100644 --- a/shaders/manif.fs +++ b/shaders/manif.fs @@ -2,6 +2,7 @@ in vec4 pos_model; in vec3 vec_normal; +in vec4 smcoord; out vec4 fragColor; @@ -11,6 +12,7 @@ uniform vec4 couleur; uniform vec4 lumPos[max]; uniform mat4 view; uniform vec4 lumColor[max]; +uniform sampler2D sm; 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 smpcoord = smcoord.xyz / smcoord.w; + if(texture(sm, smpcoord.xy).r < smpcoord.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..6bbc237 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 smcoord; 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; + smcoord = 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/manif.c b/src/manif.c index 9653047..f136733 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, _smTex = 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,69 @@ 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, &_smTex); + glBindTexture(GL_TEXTURE_2D, _smTex); + 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); + glBindFramebuffer(GL_FRAMEBUFFER, _fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + _smTex, 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, 0); + 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]; @@ -97,10 +149,22 @@ static void draw(void) { } int max_gpu = 3; // HEROS_NUMBER; - glUniform4fv(glGetUniformLocation(_pId, "lumPos"), max_gpu, (float *)lumpos); - glUniform4fv(glGetUniformLocation(_pId, "lumColor"), max_gpu, + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _smTex); + glUniform4fv(glGetUniformLocation(_pId[0], "lumPos"), max_gpu, + (float *)lumpos); + glUniform4fv(glGetUniformLocation(_pId[0], "lumColor"), max_gpu, (float *)lumcolor); + glUniform1i(glGetUniformLocation(_pId[0], "sm"), 0); deplacement += (float)(0.4 * M_PI * dt); glUseProgram(0); } + +static void deinit(void) { + if (_fbo) { + glDeleteTextures(1, &_smTex); + glDeleteFramebuffers(1, &_fbo); + _fbo = 0; + } +}