173 lines
4.5 KiB
C++
173 lines
4.5 KiB
C++
// 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 "glm/glm.hpp"
|
|
#include "glm/gtc/matrix_transform.hpp"
|
|
#include <GL/glew.h>
|
|
#include <GLFW/glfw3.h>
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include "gfx.hpp"
|
|
#include "icosphere.hpp"
|
|
|
|
#include <cmath>
|
|
#include "astro/twoBodyMethods.hpp"
|
|
|
|
// Initialize GLFW, OpenGL and GLEW, open a window and make it the current context.
|
|
// Returns 0 for success, and -1 for any failure.
|
|
// Failures are printed to STDERR.
|
|
int initGraphics(GLFWwindow** window)
|
|
{
|
|
// Set up GLFW, OpenGL and GLEW.
|
|
if (!glfwInit())
|
|
{
|
|
std::cerr << "Failed to initialize GLFW" << std::endl;
|
|
return -1;
|
|
}
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
|
|
*window = glfwCreateWindow(640, 480, "Hello Astro", NULL, NULL);
|
|
if (!window)
|
|
{
|
|
glfwTerminate();
|
|
std::cerr << "Failed to open window with GLFW" << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
glfwMakeContextCurrent(*window);
|
|
|
|
glewExperimental = GL_TRUE;
|
|
if (glewInit() != GLEW_OK)
|
|
{
|
|
std::cerr << "Failed to initialize GLEW" << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
GLint getShaderUniformLocation(GLuint shaderProgram, const std::string& uniformName)
|
|
{
|
|
GLint location = glGetUniformLocation(shaderProgram, uniformName.c_str());
|
|
if (location == -1)
|
|
{
|
|
std::cerr << "Could not find uniform: " << uniformName << std::endl;
|
|
return -1;
|
|
}
|
|
|
|
return location;
|
|
}
|
|
|
|
void updateProjectionMatrix(GLuint shaderProgram)
|
|
{
|
|
// Calculate matrices
|
|
float left = -1.0, right = 1.0, bottom = -1.0, top = 1.0, near = -1.0, far = 1.0;
|
|
glm::mat4 projection = glm::ortho(left, right, bottom, top, near, far);
|
|
GLint projectionLocation = getShaderUniformLocation(shaderProgram, "_Projection");
|
|
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, &projection[0][0]);
|
|
}
|
|
|
|
void updateModelMatrix(GLuint shaderProgram, float time)
|
|
{
|
|
constexpr float angle = glm::radians(10.0);
|
|
glm::vec3 axis = glm::vec3(0.0, 1.0, 0.0);
|
|
glm::mat4 model = glm::rotate(glm::mat4(1.0), angle * time, axis);
|
|
GLint modelLocation = getShaderUniformLocation(shaderProgram, "_Model");
|
|
glUniformMatrix4fv(modelLocation, 1, GL_FALSE, &model[0][0]);
|
|
}
|
|
|
|
void updateViewMatrix(GLuint shaderProgram)
|
|
{
|
|
glm::mat4 view = glm::mat4(1.0);
|
|
GLint viewLocation = getShaderUniformLocation(shaderProgram, "_View");
|
|
glUniformMatrix4fv(viewLocation, 1, GL_FALSE, &view[0][0]);
|
|
}
|
|
|
|
void updateModelViewProjectionMatrix(GLuint shaderProgram, float time)
|
|
{
|
|
// Calculate matrices
|
|
updateProjectionMatrix(shaderProgram);
|
|
updateModelMatrix(shaderProgram, time);
|
|
updateViewMatrix(shaderProgram);
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// Calculate period of ISS orbit around the Earth
|
|
const float semiMajorAxis = 6738000;
|
|
const float gravitationalParameter = 3.986e14;
|
|
float period = astro::computeKeplerOrbitalPeriod(semiMajorAxis, gravitationalParameter);
|
|
period /= 60.0;
|
|
std::cout << period << std::endl;
|
|
|
|
glm::vec3 v(0.0, 1.0, 2.0);
|
|
std::cout << "(" << v.x << ", " << v.y << ", " << v.z << ")" << std::endl;
|
|
|
|
GLFWwindow* window = nullptr;
|
|
if (initGraphics(&window) != 0)
|
|
return -1;
|
|
|
|
GLuint shaderProgram = compileShaderProgram();
|
|
Icosphere sphere(2);
|
|
|
|
// Main loop
|
|
while (!glfwWindowShouldClose(window))
|
|
{
|
|
glClearColor(0.2, 0.3, 0.3, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
// Render everything with the same shaders
|
|
glUseProgram(shaderProgram);
|
|
|
|
// Update uniforms
|
|
updateModelViewProjectionMatrix(shaderProgram, glfwGetTime());
|
|
|
|
// Render objects
|
|
sphere.render();
|
|
|
|
glfwSwapBuffers(window);
|
|
glfwPollEvents();
|
|
}
|
|
|
|
glfwTerminate();
|
|
return 0;
|
|
}
|