diff --git a/images/wall.png b/images/wall.png new file mode 100644 index 0000000..1dd652b Binary files /dev/null and b/images/wall.png differ diff --git a/shaders/tag.fs b/shaders/tag.fs index b738ab3..3c0a5aa 100644 --- a/shaders/tag.fs +++ b/shaders/tag.fs @@ -1,4 +1,23 @@ #version 330 -void main() { +in vec3 vsoNormal; +in vec4 vsoModPos; + +in vec2 vsoTexCoord; + +out vec4 fragColor; + +uniform sampler2D tex0; +uniform mat4 viewMatrix; +uniform vec4 lumPos; + +void main(void) { + const vec3 Vu = vec3(0, 0, -1); + vec4 lumPosv = viewMatrix * lumPos; + vec3 Ld = normalize(vsoModPos - lumPosv).xyz; + vec3 reflexion = normalize(reflect(Ld, vsoNormal)); + float ispec = pow(clamp(dot(-Vu, reflexion), 0., 1.), 20); + float phongIL = clamp(dot(-Ld, vsoNormal), 0., 1.); + + fragColor = phongIL * texture(tex0, vsoTexCoord) + ispec * vec4(1); } diff --git a/shaders/tag.vs b/shaders/tag.vs index b738ab3..18bdf67 100644 --- a/shaders/tag.vs +++ b/shaders/tag.vs @@ -1,4 +1,33 @@ #version 330 -void main() { +layout(location = 0) in vec3 vsiPosition; +layout(location = 1) in vec3 vsiNormal; +layout(location = 2) in vec2 vsiTexCoord; + +out vec2 vsoTexCoord; +out vec3 vsoNormal; +out vec4 vsoModPos; +out float vsoIntensiteLum; + +uniform mat4 proj, model, view; + +uniform vec4 lumPos; +uniform float phase; + +void main(void) { + mat4 N = transpose(inverse(view * model)); + vsoNormal = normalize((N * vec4(vsiNormal, 0)).xyz); + vec4 lumPosv = view * lumPos; + + float dist = length(vsiPosition.xz), freq = 5, amplitude = 0.1 * (sqrt(2.) - dist); + float y = amplitude * cos(phase + freq * dist); + vec3 p = vec3(vsiPosition.x, y, vsiPosition.z); + + vsoModPos = view * model * vec4(p, 1); + vec3 Ld = normalize(vsoModPos - lumPosv).xyz; + + vsoIntensiteLum = clamp(dot(-Ld, vsoNormal), 0., 1.); + gl_Position = proj * vsoModPos; + + vsoTexCoord = vec2(vsiTexCoord.x, 1 - vsiTexCoord.y); } diff --git a/src/tag.c b/src/tag.c index 0ec10c2..99d99c2 100644 --- a/src/tag.c +++ b/src/tag.c @@ -1,9 +1,16 @@ #include "../includes/animations.h" static GLuint _pId = 0; +static GLuint _murId = 0; +static GLuint _texId = 0; + +static const char *matrix_proj = "proj"; +static const char *matrix_model = "model"; +static const char *matrix_view = "view"; static void init(void); static void draw(void); +static void deinit(void); void tag(int state) { switch (state) { @@ -15,20 +22,71 @@ void tag(int state) { draw(); break; + case GL4DH_FREE: + deinit(); + break; + default: break; } } static void init(void) { + _murId = gl4dgGenGrid2df(100, 100); _pId = gl4duCreateProgram("shaders/tag.vs", "shaders/tag.fs", NULL); + + glGenTextures(1, &_texId); + load_img("images/wall.png", _texId); + + gl4duGenMatrix(GL_FLOAT, matrix_proj); + gl4duGenMatrix(GL_FLOAT, matrix_model); + gl4duGenMatrix(GL_FLOAT, matrix_view); } static void draw(void) { + static double t0 = 0; + float dt = (float)get_dt(&t0, GL_TRUE); + + static GLfloat angle = 0.0f; + GLfloat lum_pos[] = {-2.0f * + (float)cos(angle * (GLfloat)M_PI / (5.0f * 180.0f)), + 0.2f, 0.0f, 1.0f}; + glEnable(GL_DEPTH_TEST); glClearColor(0.2f, 0.2f, 0.2f, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(_pId); + bindAndLoadf(matrix_proj); + GLfloat ratio = (GLfloat)_dims[0] / (GLfloat)_dims[1]; + gl4duFrustumf(-1, 1, -ratio, ratio, 2, 1000); + + bindAndLoadf(matrix_view); + const GLfloat distance = 2; // distance from the scene + gl4duLookAtf(0, distance, distance, 0, 0, 0, 0, 1, 0); + // gl4duRotatef(-90, 0, 1, 0); // rotation camera + + bindAndLoadf(matrix_model); + gl4duRotatef(40, 1, 0, 0); + gl4duRotatef(40, 0, 0, 1); + + angle += dt * 90.0f; + gl4duSendMatrices(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, _texId); + glUniform1f(glGetUniformLocation(_pId, "phase"), 0); + glUniform4fv(glGetUniformLocation(_pId, "lumPos"), 1, lum_pos); + + gl4dgDraw(_murId); + glUseProgram(0); + glBindTexture(GL_TEXTURE_2D, 0); +} + +static void deinit(void) { + if (_texId) { + glDeleteTextures(1, &_texId); + _texId = 0; + } }