#define NOMINMAX #define _USE_MATH_DEFINES #include #include #define GLFW_INCLUDE_GLU #include #include "icosahedron.h" #include "mesh_to_vao.h" #include "print_opengl_info.h" #include "get_seconds.h" #include "report_gl_error.h" #include "create_shader_program_from_files.h" #include "last_modification_time.h" #include #include #include #include #include #include #include #include #include // From CMAKE preprocessor std::string cmakelists_dir = CMAKELISTS_SOURCE_DIR; // Default width and height int width = 640; int height = 360; GLuint prog_id = 0; // OpenGL index to shader // some user input state bool wire_frame = false; bool mouse_down = false; bool is_animating = true; double last_time = 0; double animation_seconds = 0; Eigen::Affine3f view = Eigen::Affine3f::Identity() * Eigen::Translation3f(Eigen::Vector3f(0, 0, -10)); Eigen::Matrix4f proj = Eigen::Matrix4f::Identity(); GLuint VAO; // Mesh data: RowMajor is important to directly use in OpenGL Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor> V; Eigen::Matrix F; // needs to be included here #include "glHelper.h" int main(int argc, char* argv[]) { // Process command line args int task = -1; if (argc == 2) { try { task = std::stoi(argv[1]); // char* to int std::cout << "Using glsl files for task " << task << std::endl; } catch (...) { std::cout << "Error: failed to parse second argument to an int: " << argv[1] << std::endl; } } if (task < 0 || task > 8) { std::cout << "Usage:" << std::endl; std::cout << " Unix: ./shaderpipeline " << std::endl; std::cout << " Windows: shaderpipeline.exe " << std::endl; std::cout << "where is an int in [0, 8]" << std::endl; std::cout << "For example: ./shaderpipeline 0" << std::endl; return 0; } GlHelper glHelper(task); GLFWwindow* window = glHelper.createWindow(); if (!window) { return -1; } print_opengl_info(window); igl::opengl::report_gl_error("init"); glHelper.setPerspectiveMatrixBasedOnWindowScale(); glHelper.createVAO(); glHelper.setKeyboardAndMouseCallbacks(); // Enable depth testing and delete faces seen from the back glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); // Bind the VAO, which knows where to find the vertex and triangle data glBindVertexArray(VAO); // Main display routine while (!glfwWindowShouldClose(window)) { double tic = get_seconds(); // Compile the glsl files into a shader program if (!glHelper.compileShaderIfChanged()) { std::cout << "Error: failed to compile shader" << std::endl; break; } // Clear screen glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Set viewport and output framebuffer size glfwGetFramebufferSize(window, &::width, &::height); glViewport(0, 0, ::width, ::height); // Update the uniforms used in the GLSL shaders glHelper.updateShaderUniforms(); // Render an icosahedron for the planet and moon for (int i = 0; i < 2; i++) { // Set the shader uniform "is_moon" glUniform1i(glGetUniformLocation(prog_id, "is_moon"), i == 1); // Draw the vertices in the VAO glDrawElements(GL_PATCHES, F.size(), GL_UNSIGNED_INT, 0); } // Swap the front and back buffers glfwSwapBuffers(window); // 60 fps { glfwPollEvents(); double duration = 1000000. * (get_seconds() - tic); // In microseconds const double min_duration = 1000000. / 60.; if (duration < min_duration) { std::this_thread::sleep_for(std::chrono::microseconds((int)(min_duration - duration))); } } } // Graceful exit glfwDestroyWindow(window); glfwTerminate(); return 1; }