// To compile on Windows // Install GLFW 3.3.8 // https://www.glfw.org/download.html // Install GLEW 2.2.0 // https://github.com/nigels-com/glew/releases/tag/glew-2.2.0 // // extract the downloaded .zip files to "C:/libs"; this is currently expected // by our CMakeLists.txt. // Install CMake // https://cmake.org/download // Add to PATH for all users // from project root: // mkdir build // cd build // cmake .. // cmake --build . // The last step compiles the executable - this can also be done from Visual // Studio // To run in VS // Set startup project in Solution Explorer // Press F5 to run // To run in VSCode // https://code.visualstudio.com/docs/cpp/config-mingw // To compile on Arch Linux // // Install dependencies // sudo pacman -S glfw mesa glew // // Build // cmake .. // cmake --build . #include #include #include #include #include "gfx.hpp" #include "icosphere.hpp" #include "orbit.hpp" #include "orbiter.hpp" #include "widget.hpp" // INPUT! // // what input do we even want in the first place? // * camera controls - this is a rendering only concern which needn't affect the orbital // * model validation - we want to modify orbits over time to confirm that our model is // working properly // // TODO: input can only be directly handled by static methods, so we need to find a way to collect // input from object instances and handle it at a higher level. in the case of this class, we want // to determine when a configurable key is pressed. alternatively, we can split the behaviour into // multiple sub-classes and run different loops at the top level? // // another idea is to process all input into a well-defined Input struct in the main loop, then // pass this struct into objects' render() method. // // it's possible the first idea makes the most sense if the plan is to ultimately extract the orbit // stuff to a library, since it keeps input a separate concern from the physics model struct Input { bool cycleAnimation; } input; void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_C && action == GLFW_PRESS) { input.cycleAnimation = true; } } void clearInput() { input.cycleAnimation = false; } int main() { GLFWwindow* window = nullptr; if (initGraphics(&window, "Hello Astro") != 0) return -1; GLuint litProgram = compileShaderProgram("./frag_lit.glsl"); GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl"); // set up scene Icosphere planet(0.2, 3, litProgram); std::vector keplerianElements(6); keplerianElements[astro::semiMajorAxisIndex] = .75; keplerianElements[astro::eccentricityIndex] = .5; keplerianElements[astro::inclinationIndex] = 3.142 / 2.0 + 1; keplerianElements[astro::argumentOfPeriapsisIndex] = 2.0; keplerianElements[astro::longitudeOfAscendingNodeIndex] = 0; Orbit orbit(keplerianElements, unlitProgram); Icosphere orbiterSphere(0.07, 2, litProgram); Orbiter orbiter(orbiterSphere, orbit, unlitProgram); // register input glfwSetKeyCallback(window, keyCallback); // Main loop while (!glfwWindowShouldClose(window)) { // receive input - key callback populates input struct defined further up, // clearInput() needs to be called to clear input from previous frame clearInput(); glfwPollEvents(); // apply input if (input.cycleAnimation) { orbiter.cycleAnimation(); } // rendering glClearColor(0.2, 0.3, 0.3, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float time = glfwGetTime(); planet.render(time); orbiter.render(time); glfwSwapBuffers(window); } glfwTerminate(); return 0; }