#include "../src/adapters/adapter.hpp" #include "../src/scene.hpp" #include "../src/camera.hpp" #include "../src/lights/sun.hpp" #include "../src/models/raw.hpp" #include "../src/models/static.hpp" #include "../src/objects/with_model.hpp" #include #include #include #include #include static Store store; static const Adapter adapter(store); static void iterate(); static GLFWCALL void on_key(int key, int action); static EM_BOOL on_em_mousemove(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data); static bool keys[GLFW_KEY_LAST]; static Scene scene; static Lights::Sun sun; static Camera camera(scene); static float camera_angles_y = 0; static float camera_angles_x = 0; static const Model *protagonist; static const Model *car; static const Model *suzanne; static const Model *teapot; static const Model *bunny; static const Model *untitled; static Object *protagonist1; static Object *car1; static Object *suzanne1; static Object *teapot1; static Object *bunny1; static Object *untitled1; static bool in_car = false; static float car_vel = 0.0; int main() { if (!glfwInit()) exit(EXIT_FAILURE); if (!glfwOpenWindow(640, 480, 8, 8, 8, 8, 16, 0, GLFW_WINDOW)) { glfwTerminate(); exit(EXIT_FAILURE); } if (glewInit() != GLEW_OK) { glfwCloseWindow(); glfwTerminate(); exit(EXIT_FAILURE); } glfwSetKeyCallback(on_key); emscripten_set_mousemove_callback(nullptr, nullptr, false, on_em_mousemove); sun.ambient = glm::vec3(0.2, 0.2, 0.2); sun.diffuse = glm::vec3(1.0, 1.0, 1.0); sun.specular = glm::vec3(1.0, 1.0, 1.0); sun.direction = glm::vec3(0.0, 0.0, -1.0); camera.projection = glm::perspective(45.0f, (float)640 / (float)480, 0.1f, 100.0f); protagonist = adapter.load("protagonist.obj"); car = adapter.load("car.obj"); suzanne = adapter.load("suzanne.obj"); teapot = adapter.load("teapot.obj"); bunny = adapter.load("bunny.obj"); untitled = adapter.load("untitled.raw"); protagonist1 = new Objects::WithModel(*protagonist); protagonist1->position.z = 4; car1 = new Objects::WithModel(*car); car1->position.z = -10; suzanne1 = new Objects::WithModel(*suzanne); suzanne1->position.z = -2; suzanne1->position.y = 2; teapot1 = new Objects::WithModel(*teapot); teapot1->position.x = -2.0; teapot1->position.y = 1.0; teapot1->angles.y = 45; bunny1 = new Objects::WithModel(*bunny); bunny1->position.x = 2.0; untitled1 = new Objects::WithModel(*untitled); untitled1->position.x = -6; scene << &sun << protagonist1 << car1 << suzanne1 << teapot1 << bunny1 << untitled1; glViewport(0, 0, 640, 480); glEnable(GL_DEPTH_TEST); glClearColor(1, 1, 1, 0); emscripten_set_main_loop(iterate, 0, 1); } void iterate() { if (in_car) { protagonist1->position = car1->position; if (keys[(unsigned char)'W']) car_vel += 0.1; if (keys[(unsigned char)'S']) car_vel -= 0.1; if (car_vel > 2.0) car_vel = 2.0; else if (car_vel < -1.0) car_vel = -1.0; if (keys[(unsigned char)'A']) car1->angles.y += 0.5 * car_vel; if (keys[(unsigned char)'D']) car1->angles.y -= 0.5 * car_vel; if (car1->angles.y < 0) car1->angles.y = 359; if (car1->angles.y >= 360) car1->angles.y = 0; } else { car_vel *= 0.99; protagonist1->angles.y = camera_angles_y; if (keys[(unsigned char)'W']) { protagonist1->position.x -= 0.1 * sin(glm::radians(protagonist1->angles.y)); protagonist1->position.z -= 0.1 * cos(glm::radians(protagonist1->angles.y)); } if (keys[(unsigned char)'S']) { protagonist1->position.x += 0.1 * sin(glm::radians(protagonist1->angles.y)); protagonist1->position.z += 0.1 * cos(glm::radians(protagonist1->angles.y)); } if (keys[(unsigned char)'D']) { protagonist1->position.x += 0.1 * cos(glm::radians(protagonist1->angles.y)); protagonist1->position.z -= 0.1 * sin(glm::radians(protagonist1->angles.y)); } if (keys[(unsigned char)'A']) { protagonist1->position.x -= 0.1 * cos(glm::radians(protagonist1->angles.y)); protagonist1->position.z += 0.1 * sin(glm::radians(protagonist1->angles.y)); } } car1->position.x += car_vel * 0.1 * sin(glm::radians(car1->angles.y)); car1->position.z += car_vel * 0.1 * cos(glm::radians(car1->angles.y)); if (in_car) { camera.base = car1->transformation() * glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), glm::radians(camera_angles_y), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), glm::radians(camera_angles_x), glm::vec3(1.0f, 0.0f, 0.0f)); camera.position.z = 8; } else { camera.base = protagonist1->transformation() * glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 2.0f, 0.0f)) * glm::rotate(glm::mat4(1.0f), glm::radians(camera_angles_x), glm::vec3(1.0f, 0.0f, 0.0f)); camera.position.z = 2; } suzanne1->angles.z = glfwGetTime() * 360 / 4; teapot1->angles.x = glfwGetTime() * 360 / 6; bunny1->angles.y = glfwGetTime() * 360 / 2; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera.draw(); } GLFWCALL void on_key(int key, int action) { keys[key] = action != GLFW_RELEASE; if (key == 'E' && action == GLFW_PRESS) { if (in_car) { in_car = false; protagonist1->visible = true; } else if (glm::distance(protagonist1->position, car1->position) <= 1.0) { in_car = true; protagonist1->visible = false; } } } EM_BOOL on_em_mousemove(__attribute__((unused)) int event_type, const EmscriptenMouseEvent *mouse_event, __attribute__((unused)) void *user_data) { camera_angles_y -= mouse_event->movementX; camera_angles_x -= mouse_event->movementY; if (camera_angles_y < 0) camera_angles_y = 359; else if (camera_angles_y >= 360) camera_angles_y = 0; if (camera_angles_x < -90) camera_angles_x = -90; else if (camera_angles_x > 90) camera_angles_x = 90; return true; }