aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/space-simulator.cpp289
1 files changed, 289 insertions, 0 deletions
diff --git a/src/game/space-simulator.cpp b/src/game/space-simulator.cpp
new file mode 100644
index 0000000..1d2bff0
--- /dev/null
+++ b/src/game/space-simulator.cpp
@@ -0,0 +1,289 @@
+#include <stdio.h>
+
+#include <GL/glew.h>
+
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#include "../application/Application.hpp"
+#include "../window/Window.hpp"
+#include "../window/EventsManager.hpp"
+#include "../window/Events.hpp"
+#include "../graphics/Camera.hpp"
+#include "../graphics/Mesh.hpp"
+#include "../graphics/Shader.hpp"
+#include "../graphics/Texture.hpp"
+#include "CelestialObject.hpp"
+#include "objects.hpp"
+
+using namespace glm;
+
+#define DAY_SLASH_SEC 1.0f
+#define MONTH_SLASH_SEC 30.5f
+#define YEAR_SLASH_SEC 365.0f
+
+int init_shader(ShaderManager *main, ShaderManager *skybox)
+{
+ int result;
+ Shader main_sh[2], skybox_sh[2];
+
+ // =========== Vertex shader ===========
+ result = main_sh[0].Compile("main.vs", GL_VERTEX_SHADER);
+ if(result) {
+ fprintf(stderr, "\"main.vs\": %s\n", main_sh[0].GetError());
+ return 1;
+ }
+ result = skybox_sh[0].Compile("skybox.vs", GL_VERTEX_SHADER);
+ if(result) {
+ fprintf(stderr, "\"skybox.vs\": %s\n", skybox_sh[0].GetError());
+ return 1;
+ }
+
+ // =========== Fragment shader ===========
+ result = main_sh[1].Compile("main.frag", GL_FRAGMENT_SHADER);
+ if(result) {
+ fprintf(stderr, "\"main.frag\": %s\n", main_sh[1].GetError());
+ return 1;
+ }
+ result = skybox_sh[1].Compile("skybox.frag", GL_FRAGMENT_SHADER);
+ if(result) {
+ fprintf(stderr, "\"skybox.frag\": %s\n", skybox_sh[1].GetError());
+ return 1;
+ }
+
+ // =========== Link shaders in Manager ===========
+ result = main->Link(main_sh, 2);
+ if(result)
+ return 1;
+ result = skybox->Link(skybox_sh, 2);
+ if(result)
+ return 1;
+
+ return 0;
+}
+
+CelestialObject *init_solar_system()
+{
+ Texture *sun_texture = new Texture(GL_TEXTURE_2D);
+ sun_texture->LoadImage("content/sun.jpg");
+ CelestialObject *sun = new CelestialObject(sun_texture);
+ sun->SetPeriod(0.0f, 25.37f);
+ sun->SetRadius(5.0f, 0.0f);
+ sun->SetTilts(7.25f, 0.0f);
+
+ Texture *mercury_texture = new Texture(GL_TEXTURE_2D);
+ mercury_texture->LoadImage("content/mercury.jpg");
+ CelestialObject *mercury = new CelestialObject(mercury_texture);
+ mercury->SetPeriod(87.97f, 58.64f);
+ mercury->SetRadius(0.38f, 6.9f);
+ mercury->SetTilts(0.01f, 7.01f);
+
+ Texture *venus_texture = new Texture(GL_TEXTURE_2D);
+ venus_texture->LoadImage("content/venus.jpg");
+ CelestialObject *venus = new CelestialObject(venus_texture);
+ venus->SetPeriod(224.7f, -243.01);
+ venus->SetRadius(0.95f, 13.8f);
+ venus->SetTilts(177.36f, 3.39f);
+
+ Texture *earth_texture = new Texture(GL_TEXTURE_2D);
+ earth_texture->LoadImage("content/earth.jpg");
+ CelestialObject *earth = new CelestialObject(earth_texture);
+ earth->SetPeriod(365.25f, 1.0f);
+ earth->SetRadius(1.0f, 20.7f);
+ earth->SetTilts(23.0f, 0.0f);
+
+ Texture *moon_texture = new Texture(GL_TEXTURE_2D);
+ moon_texture->LoadImage("content/moon.jpg");
+ CelestialObject *moon = new CelestialObject(moon_texture);
+ moon->SetPeriod(27.32f, 27.32f);
+ moon->SetRadius(0.1f, 0.5f);
+ moon->SetTilts(1.54f, 23.45f);
+
+ Texture *mars_texture = new Texture(GL_TEXTURE_2D);
+ mars_texture->LoadImage("content/mars.jpg");
+ CelestialObject *mars = new CelestialObject(mars_texture);
+ mars->SetPeriod(686.98f, 1.02f);
+ mars->SetRadius(0.53f, 31.05f);
+ mars->SetTilts(25.19f, 1.85f);
+
+ Texture *jupiter_texture = new Texture(GL_TEXTURE_2D);
+ jupiter_texture->LoadImage("content/jupiter.jpg");
+ CelestialObject *jupiter = new CelestialObject(jupiter_texture);
+ jupiter->SetPeriod(365.25f * 11.86f, 0.41f);
+ jupiter->SetRadius(4.8f, 93.15f);
+ jupiter->SetTilts(3.13f, 1.31f);
+
+ Texture *saturn_texture = new Texture(GL_TEXTURE_2D);
+ saturn_texture->LoadImage("content/saturn.jpg");
+ CelestialObject *saturn = new CelestialObject(saturn_texture);
+ saturn->SetPeriod(365.25f * 29.46f, 0.44f);
+ saturn->SetRadius(4.5f, 172.32f);
+ saturn->SetTilts(26.73f, 2.49f);
+
+ Texture *uranus_texture = new Texture(GL_TEXTURE_2D);
+ uranus_texture->LoadImage("content/uranus.jpg");
+ CelestialObject *uranus = new CelestialObject(uranus_texture);
+ uranus->SetPeriod(365.25f * 84.02f, -0.71f);
+ uranus->SetRadius(4.0f, 244.65f);
+ uranus->SetTilts(97.77f, 0.77f);
+
+ Texture *neptune_texture = new Texture(GL_TEXTURE_2D);
+ neptune_texture->LoadImage("content/neptune.jpg");
+ CelestialObject *neptune = new CelestialObject(neptune_texture);
+ neptune->SetPeriod(365.25f * 168.78f, 0.67f);
+ neptune->SetRadius(3.88f, 517.0f);
+ neptune->SetTilts(28.32f, 1.77f);
+
+ /* set dependencies: master to slave */
+ sun->AddSlave(mercury);
+ sun->AddSlave(venus);
+ sun->AddSlave(earth);
+ earth->AddSlave(moon);
+ sun->AddSlave(mars);
+ sun->AddSlave(jupiter);
+ sun->AddSlave(saturn);
+ sun->AddSlave(uranus);
+ sun->AddSlave(neptune);
+ return sun;
+}
+
+int main(int argc, char *argv[])
+{
+ int window_width = 1280;
+ int window_height = 720;
+ int result;
+ result = Application::Init();
+ if(result) {
+ fprintf(stderr, "Error: application initialization failed\n");
+ return 1;
+ }
+
+ Window *game_window;
+ ShaderManager main_shader;
+ ShaderManager skybox_shader;
+
+ game_window = Window::Initialize(
+ window_width, window_height, "Space Simulator");
+ if(!game_window) {
+ fprintf(stderr, "Error: window initialization failed\n");
+ Application::Terminate();
+ return 1;
+ }
+ game_window->MakeContextCurrent();
+
+ result = init_shader(&main_shader, &skybox_shader);
+ if(result) {
+ fprintf(stderr, "Error: shader initialization failed\n");
+ Application::Terminate();
+ return 1;
+ }
+
+ Events game_events(game_window);
+ EventsManager::AddListener(&game_events, EM_LISTEN_KEY | EM_LISTEN_CURSOR |
+ EM_LISTEN_MBUTTON | EM_LISTEN_WINDOWSIZE | EM_LISTEN_MSCROLL);
+
+ // =========== load skybox ===========
+ const char *skybox_images[] = {
+ "content/skybox_right.jpg",
+ "content/skybox_left.jpg",
+ "content/skybox_top.jpg",
+ "content/skybox_bottom.jpg",
+ "content/skybox_front.jpg",
+ "content/skybox_back.jpg"
+ };
+
+ Texture skybox_texture(GL_TEXTURE_CUBE_MAP);
+ result = skybox_texture.LoadImage(skybox_images);
+ if(result) {
+ fprintf(stderr, "Error: skybox load failed\n");
+ Application::Terminate();
+ return 1;
+ }
+
+ // =========== create objects ===========
+ Mesh *object_cube = form_cube();
+
+ CelestialObject::InitializeMesh();
+ CelestialObject *sun = init_solar_system();
+
+ // =========== shader context ===========
+ mat4 proj_view(1.0f);
+
+ Camera cam(vec3(0.0f, 10.0f, 40.0f));
+ cam.SetSpeed(30.0f);
+ cam.SetPerspective(45.0f, 0.1f, 1000.0f);
+
+ GLuint modelLoc, proj_viewLoc, skyboxLoc;
+ modelLoc = glGetUniformLocation(main_shader.GetID(), "model");
+ proj_viewLoc = glGetUniformLocation(main_shader.GetID(), "proj_view");
+ skyboxLoc = glGetUniformLocation(skybox_shader.GetID(), "proj_view");
+
+ // =========== pre game loop ===========
+ #ifdef WIREFRAME_MODE
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ #endif
+ glEnable(GL_DEPTH_TEST);
+
+ GLfloat deltaTime = 0.0f, lastFrame = 0.0f;
+
+ // =========== game loop ===========
+ while(!game_window->IsShouldClose()) {
+ GLfloat currentFrame = Application::GetTime();
+ deltaTime = currentFrame - lastFrame;
+ lastFrame = currentFrame;
+
+ game_window->GetWinSize(window_width, window_height);
+
+ // =========== handle input ===========
+ EventsManager::PollEvents();
+ if(game_events.Jpressed(KEY_ESCAPE))
+ game_window->SetShouldClose(1);
+ if(game_events.Jpressed(KEY_TAB))
+ game_window->ToggleCursorMode();
+
+ if(game_events.Pressed(KEY_W))
+ cam.Movement(FORWARD, deltaTime);
+ if(game_events.Pressed(KEY_S))
+ cam.Movement(BACKWARD, deltaTime);
+ if(game_events.Pressed(KEY_A))
+ cam.Movement(LEFT, deltaTime);
+ if(game_events.Pressed(KEY_D))
+ cam.Movement(RIGHT, deltaTime);
+
+ float delta_x = game_events.GetDX();
+ float delta_y = game_events.GetDY();
+ if(delta_x || delta_y)
+ cam.UpdateView(delta_x, delta_y);
+
+ delta_y = game_events.GetScrollDY();
+ if(delta_y)
+ cam.UpdateFov(delta_y);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // =========== draw skybox ===========
+ glDepthMask(GL_FALSE);
+ skybox_shader.Use();
+ skybox_texture.Bind();
+
+ proj_view = cam.GetSkyboxMatrix(window_width, window_height);
+ glUniformMatrix4fv(skyboxLoc, 1, GL_FALSE, value_ptr(proj_view));
+ object_cube->Draw();
+ glDepthMask(GL_TRUE);
+
+ // =========== draw space objects ===========
+ main_shader.Use();
+
+ proj_view = cam.GetProjViewMatrix(window_width, window_height);
+ glUniformMatrix4fv(proj_viewLoc, 1, GL_FALSE, value_ptr(proj_view));
+ sun->Draw(lastFrame, MONTH_SLASH_SEC, modelLoc);
+
+ game_window->SwapBuffers();
+ }
+
+ delete object_cube;
+ delete game_window;
+ Application::Terminate();
+ return 0;
+}