diff --git a/CMakeLists.txt b/CMakeLists.txt index 1546122..4d53fc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(SOURCES src/textrendering.cpp src/window.cpp src/collisions.cpp + src/bezierCurve.cpp ) cmake_minimum_required(VERSION 3.5.0) diff --git a/bin/Debug/main.exe b/bin/Debug/main.exe index 63e1491..88e3d8c 100644 Binary files a/bin/Debug/main.exe and b/bin/Debug/main.exe differ diff --git a/data/laminate_floor_02_diff_4k.jpg b/data/laminate_floor_02_diff_4k.jpg new file mode 100644 index 0000000..abf1d42 Binary files /dev/null and b/data/laminate_floor_02_diff_4k.jpg differ diff --git a/include/bezierCurve.h b/include/bezierCurve.h new file mode 100644 index 0000000..7c610a9 --- /dev/null +++ b/include/bezierCurve.h @@ -0,0 +1,8 @@ +#ifndef _BEZIERCURVE_H +#define _BEZIERCURVE_H + +#include "globals.h" + +glm::vec4 bezierCurve(float t, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3); + +#endif // _BEZIERCURVE_H \ No newline at end of file diff --git a/src/bezierCurve.cpp b/src/bezierCurve.cpp new file mode 100644 index 0000000..8a0fc23 --- /dev/null +++ b/src/bezierCurve.cpp @@ -0,0 +1,16 @@ +#include "bezierCurve.h" + +glm::vec4 bezierCurve(float t, glm::vec3 p0, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3) { + float u = 1 - t; + float tt = t * t; + float uu = u * u; + float uuu = uu * u; + float ttt = tt * t; + + glm::vec3 p = uuu * p0; + p += 3 * uu * t * p1; + p += 3 * u * tt * p2; + p += ttt * p3; + + return glm::vec4(p, 1); +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d22f446..4adbd87 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,7 +32,7 @@ // Headers locais, definidos na pasta "include/" #include "stackMatrix.h" #include "textrendering.h" -// #include "callback.h" +#include "bezierCurve.h" #include "window.h" #include "collisions.h" @@ -50,7 +50,7 @@ int main(int argc, char* argv[]) // Criamos uma janela do sistema operacional, com 800 colunas e 600 linhas // de pixels GLFWwindow* window; - window = glfwCreateWindow(800, 600, "INF01047: Trabalho final", NULL, NULL); + window = glfwCreateWindow(800, 600, "Computer Engineering for Babies", NULL, NULL); createWindow(window); setCallbacks(window); @@ -76,6 +76,7 @@ int main(int argc, char* argv[]) LoadTextureImage("../../data/circuits/metal_grate_rusty_diff_4k.jpg"); // TextureBlocks LoadTextureImage("../../data/circuits/leather_red_03_coll1_4k.png"); // TextureSphere LoadTextureImage("../../data/circuits/and.jpg"); // TexturePlaneAnd + LoadTextureImage("../../data/laminate_floor_02_diff_4k.jpg"); // TextureGround // Construímos a representação de objetos geométricos através de malhas de triângulos buildModel("../../data/sphere.obj"); @@ -125,6 +126,14 @@ int main(int argc, char* argv[]) // movimento no modo câmera livre glm::vec4 camera_movement = glm::vec4(0.0f,0.0f,0.0f,0.0f); + // Variáveis para controle da câmera pela curva de Bezier + bool curvedCamera = true; + float t = 0.0f; + glm::vec3 startPoint = glm::vec3(-0.1035f, 0.6f, 3.45f); + glm::vec3 endPoint = glm::vec3(0.0f, 2.0f, 0.04f); + glm::vec3 controlPoint1 = startPoint + glm::normalize(endPoint - startPoint)* 0.3f; + glm::vec3 controlPoint2 = endPoint + glm::normalize(endPoint - startPoint)* 0.3f; + // Inicializa a flag de colisão com a mesa bool isTableCollision = false; @@ -186,19 +195,41 @@ int main(int argc, char* argv[]) // os shaders de vértice e fragmentos). glUseProgram(g_GpuProgramID); + if (curvedCamera) { + float currentTimeBezier = (float)glfwGetTime(); + float deltaTime = currentTimeBezier - prev_time; + prev_time = currentTimeBezier; + t += deltaTime / 2.0f; + + if (t >= 1.0f) { + t = 1.0f; + curvedCamera = false; // Stop the camera movement + camera_position_c = glm::vec4(endPoint, 1.0f); + } + else { + camera_position_c = bezierCurve(t, startPoint, controlPoint1, controlPoint2, endPoint); + g_CameraDistance = sqrt(camera_position_c.x*camera_position_c.x + camera_position_c.y*camera_position_c.y + camera_position_c.z*camera_position_c.z); + g_CameraPhi = glm::asin(camera_position_c.y / g_CameraDistance); + g_CameraTheta = glm::atan(camera_position_c.x, camera_position_c.z); + } + } + // Computamos a posição da câmera utilizando coordenadas esféricas. As // variáveis g_CameraDistance, g_CameraPhi, e g_CameraTheta são // controladas pelo mouse do usuário. Veja as funções CursorPosCallback() // e ScrollCallback(). // Aqui, os parâmetros irão atualizar a orientação do vetor view em relação ao - // ponto c 'ancorado'. + // ponto c 'ancorado'. + float r = g_CameraDistance; float y = r*sin(g_CameraPhi); float z = r*cos(g_CameraPhi)*cos(g_CameraTheta); float x = r*cos(g_CameraPhi)*sin(g_CameraTheta); // Câmera look-at - camera_position_c = glm::vec4(x,y,z,1.0f); // Ponto "c", centro da câmera + if (curvedCamera == false){ + camera_position_c = glm::vec4(x,y,z,1.0f); // Ponto "c", centro da câmera + }; glm::vec4 camera_lookat_l = glm::vec4(0.0f,0.0f,0.0f,1.0f); // Ponto "l", para onde a câmera (look-at) estará sempre olhando glm::vec4 camera_view_vector = camera_lookat_l - camera_position_c; // Vetor "view", sentido para onde a câmera está virada @@ -271,7 +302,7 @@ int main(int argc, char* argv[]) #define PLANE_NOT 11 #define LIGHTBULB_AND 12 #define PLANE_AND 13 - #define PLANE_GROUND 14 + #define GROUND 14 #define PLANE_WIDTH 0.2f #define PLANE_HEIGHT 0.145f @@ -695,12 +726,6 @@ int main(int argc, char* argv[]) PopMatrix(model); - //Desenhamos o plano do chão - model = Matrix_Translate(0.0f,0.0f,0.0f) * Matrix_Scale(10.0f,1.0f,10.0f); - glUniformMatrix4fv(g_model_uniform, 1 , GL_FALSE , glm::value_ptr(model)); - glUniform1i(g_object_id_uniform, PLANE_GROUND); - DrawVirtualObject("the_plane"); - // Projeta um ray casting em coord. do mundo a partir das coord. do mouse g_rayPoint = MouseRayCasting(projectionMatrix, viewMatrix); glm::vec3 rayVec = glm::normalize(glm::vec4(g_rayPoint, 1.0f)); @@ -743,6 +768,16 @@ int main(int argc, char* argv[]) glUniformMatrix4fv(g_view_uniform, 1, GL_FALSE, glm::value_ptr(viewMatrix)); glUniformMatrix4fv(g_projection_uniform, 1, GL_FALSE, glm::value_ptr(projectionMatrix)); + // Desenhamos o plano do chão + model = Matrix_Translate(0.0f,0.0f,0.0f) * Matrix_Scale(100.0f,100.0f,100.0f); + glUniformMatrix4fv(g_model_uniform, 1 , GL_FALSE , glm::value_ptr(model)); + glUniform1i(g_object_id_uniform, GROUND); + DrawVirtualObject("the_plane"); + + // Imprimimos na tela os ângulos de Euler que controlam a rotação do + // terceiro cubo. + TextRendering_ShowMouseCoords(window); + // Imprimimos na informação sobre a matriz de projeção sendo utilizada. TextRendering_ShowProjection(window); diff --git a/src/objects.cpp b/src/objects.cpp index fc5fb89..5b42275 100644 --- a/src/objects.cpp +++ b/src/objects.cpp @@ -266,6 +266,7 @@ void LoadShadersFromFiles() glUniform1i(glGetUniformLocation(g_GpuProgramID, "TextureBlocks"), 10); glUniform1i(glGetUniformLocation(g_GpuProgramID, "TextureSphere"), 11); glUniform1i(glGetUniformLocation(g_GpuProgramID, "TexturePlaneAnd"), 12); + glUniform1i(glGetUniformLocation(g_GpuProgramID, "TextureGround"), 13); // Variáveis em "shader_fragment.glsl" para controle de texturas dos dígitos glUniform1i(glGetUniformLocation(g_GpuProgramID, "u_isInput1Digit0"), isInput1Digit0); diff --git a/src/shader_fragment.glsl b/src/shader_fragment.glsl index d152326..5cfcc6a 100644 --- a/src/shader_fragment.glsl +++ b/src/shader_fragment.glsl @@ -35,7 +35,7 @@ uniform mat4 projection; #define PLANE_NOT 11 #define LIGHTBULB_AND 12 #define PLANE_AND 13 -#define PLANE_GROUND 14 +#define GROUND 14 uniform int object_id; // Parâmetros da axis-aligned bounding box (AABB) do modelo @@ -55,6 +55,7 @@ uniform sampler2D TexturePlaneNot; uniform sampler2D TextureSphere; uniform sampler2D TexturePlaneAnd; uniform sampler2D TextureBlocks; +uniform sampler2D TextureGround; uniform bool u_isInput1Digit0; uniform bool u_isInput2Digit0; @@ -204,6 +205,12 @@ void main() lambertDiffuseTerm = Kd * I * lambert; color.rgb = lambertDiffuseTerm + ambientTerm + specularTerm; // Blinn-Phong } + else if (object_id == GROUND) // Blinn-Phong e Phong shading + { + Kd = texture(TextureGround, texcoords).rgb; + lambertDiffuseTerm = Kd * I * lambert; + color.rgb = lambertDiffuseTerm + ambientTerm + specularTerm; // Blinn-Phong + } else if (object_id == INPUT1_DIGIT) // Diffuse e Phong shading { if (u_isInput1Digit0) @@ -254,14 +261,6 @@ void main() lambertDiffuseTerm = Kd * I * lambert; color.rgb = lambertDiffuseTerm + ambientTerm + specularTerm; // Blinn-Phong } - else if (object_id == PLANE_GROUND) // Diffuse e Phong shading - { - U = texcoords.x; - V = texcoords.y; - Kd = texture(TextureBlocks, vec2(U,V)).rgb; - lambertDiffuseTerm = Kd * I * lambert; - color.rgb = lambertDiffuseTerm + ambientTerm; // Diffuse - } // NOTE: Se você quiser fazer o rendering de objetos transparentes, é // necessário: