skein/src/main.cpp

161 lines
4.2 KiB
C++
Raw Normal View History

2023-07-23 16:46:30 +02:00
// To compile on Windows
2023-07-24 23:15:49 +02:00
// 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
2023-07-24 23:15:49 +02:00
// by our CMakeLists.txt.
2023-07-23 16:46:30 +02:00
// Install CMake
// https://cmake.org/download
// Add to PATH for all users
// from project root:
// mkdir build
// cd build
// cmake ..
// cmake --build .
2023-07-23 17:46:53 +02:00
// The last step compiles the executable - this can also be done from Visual
// Studio
2023-07-23 16:46:30 +02:00
2023-07-23 17:46:53 +02:00
// To run in VS
// Set startup project in Solution Explorer
2023-07-24 23:15:49 +02:00
// Press F5 to run
2023-08-02 00:29:52 +02:00
// To run in VSCode
// https://code.visualstudio.com/docs/cpp/config-mingw
2023-07-24 23:15:49 +02:00
// To compile on Arch Linux
//
// Install dependencies
2023-07-24 23:31:58 +02:00
// sudo pacman -S glfw mesa glew
2023-07-24 23:15:49 +02:00
//
// Build
// cmake ..
// cmake --build .
2023-07-23 17:46:53 +02:00
2023-07-24 23:31:58 +02:00
#include <GL/glew.h>
2023-07-23 17:46:53 +02:00
#include <GLFW/glfw3.h>
2024-03-04 00:52:34 +01:00
#include <iostream>
2023-07-23 16:45:15 +02:00
#include "gfx.hpp"
2023-08-02 01:52:04 +02:00
#include "icosphere.hpp"
#include "orbiter.hpp"
#include "orbitervisualizer.hpp"
2024-08-17 22:51:42 +02:00
#include "orbitvisualizer.hpp"
#include "widget.hpp"
2024-08-17 22:51:42 +02:00
#include <skein/orbit.h>
2024-03-04 08:57:42 +01:00
// 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;
2024-03-04 00:52:34 +01:00
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_C && action == GLFW_PRESS)
{
2024-03-04 08:57:42 +01:00
input.cycleAnimation = true;
2024-03-04 00:52:34 +01:00
}
}
2024-03-04 08:57:42 +01:00
void clearInput()
{
input.cycleAnimation = false;
}
2023-07-30 23:02:20 +02:00
int main()
{
GLFWwindow* window = nullptr;
2024-08-18 01:10:20 +02:00
if (initGraphics(&window, "skeingl") != 0)
2023-07-30 23:02:20 +02:00
return -1;
2023-08-06 13:08:49 +02:00
GLuint litProgram = compileShaderProgram("./frag_lit.glsl");
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
2024-03-04 00:52:34 +01:00
// set up scene
Icosphere planet(0.2, 3, litProgram);
Orbiter orbiter;
Orbit& orbit = orbiter.getOrbit();
orbit.setSemiMajorAxis(.75);
orbit.setEccentricity(.5);
orbit.setInclination(3.142 / 2.0 + 1);
orbit.setArgumentOfPeriapsis(2.0);
orbit.setLongitudeOfAscendingNode(0.1);
2023-07-30 23:02:20 +02:00
2024-08-18 14:22:04 +02:00
OrbiterVisualizer orbiterVisualizer(orbiter, litProgram, unlitProgram);
OrbitVisualizer orbitVisualizer(orbit, unlitProgram);
2024-03-04 00:52:34 +01:00
// register input
glfwSetKeyCallback(window, keyCallback);
// TODO: convert these to an enum
const int ANIM_ORBITING = 0;
const int ANIM_ECCENTRICITY = 1;
int animation = 0;
float time = glfwGetTime();
2023-07-27 21:54:06 +02:00
// Main loop
2023-07-23 17:46:53 +02:00
while (!glfwWindowShouldClose(window))
{
2024-03-04 08:57:42 +01:00
// receive input - key callback populates input struct defined further up,
// clearInput() needs to be called to clear input from previous frame
clearInput();
2024-03-04 00:52:34 +01:00
glfwPollEvents();
2024-03-04 08:57:42 +01:00
// apply input
if (input.cycleAnimation)
{
animation++;
if (animation > ANIM_ECCENTRICITY)
{
animation = 0;
}
}
// only update time if playing the orbiting animation
if (animation == ANIM_ORBITING)
{
time = glfwGetTime();
}
else
{
float e = .25 + .2 * sin(glfwGetTime());
orbit.setEccentricity(e);
2024-03-04 08:57:42 +01:00
}
2024-03-04 00:52:34 +01:00
// rendering
glClearColor(0.2, 0.3, 0.3, 1.0);
2023-08-03 10:28:14 +02:00
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2023-07-23 18:21:44 +02:00
2024-03-04 08:57:42 +01:00
planet.render(time);
orbiterVisualizer.render(time);
2024-08-17 22:51:42 +02:00
orbitVisualizer.render(time);
2023-07-23 18:21:44 +02:00
glfwSwapBuffers(window);
2023-07-23 17:46:53 +02:00
}
glfwTerminate();
2023-07-23 16:45:15 +02:00
return 0;
2023-07-24 23:15:49 +02:00
}