AtmosphereTestScene.cpp 7.39 KB
Newer Older
Dario Seyb's avatar
Dario Seyb committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#include <engine/scene/scenes/AtmosphereTestScene.hpp>

#include <engine/ui/UISystem.hpp>

#include <ACGL/ACGL.hh>

#include <ACGL/OpenGL/Objects.hh>
#include <ACGL/Base/Settings.hh>
#include <ACGL/Math/Math.hh>
#include <ACGL/OpenGL/Data/TextureLoadStore.hh>
#include <ACGL/OpenGL/Managers.hh>

#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>
#include <ACGL/OpenGL/Creator/VertexArrayObjectCreator.hh>
#include <ACGL/OpenGL/Creator/Texture2DCreator.hh>

#include <engine/scene/Transform.hpp>
#include <engine/scene/Drawable.hpp>
#include <engine/scene/Planet.hpp>

#include <engine/events/MouseEvent.hpp>
#include <engine/events/KeyboardEvent.hpp>

#include <engine/graphics/BloomPostFX.hpp>

using namespace ACGL::OpenGL;
using namespace ACGL::Base;
using namespace ACGL::Utils;

bool AtmosphereTestScene::startup() {
  if (!Scene::startup()) {
    return false;
  }

  RESOLVE_DEPENDENCY(m_player);
  RESOLVE_DEPENDENCY(m_orbitals);

  m_renderer->addEffect<BloomPostFX>();
Dario Seyb's avatar
Dario Seyb committed
39 40 41 42 43 44 45 46
  {
    auto skyboxPassId = m_renderer->getRenderPassId("Skybox"_sh);
    auto vaoSkybox = VertexArrayObjectCreator("skybox.obj").create();
    auto skyboxShader = ShaderProgramFileManager::the()->get(ShaderProgramCreator("Skybox")
      .attributeLocations(vaoSkybox->getAttributeLocations())
      .fragmentDataLocations(m_renderer->getGBufferLocations()));

    auto skyboxTexture = Texture2DFileManager::the()->get(Texture2DCreator("skybox.png"));
Dario Seyb's avatar
Dario Seyb committed
47

Dario Seyb's avatar
Dario Seyb committed
48 49
    Geometry skyboxGeom = { vaoSkybox };
    skyboxGeom.vao->setMode(GL_PATCHES);
Dario Seyb's avatar
Dario Seyb committed
50

Dario Seyb's avatar
Dario Seyb committed
51
    Material skyboxMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 1, 1, 1, 1 }, skyboxTexture, nullptr, nullptr, skyboxShader, false, RenderQueue::OPAQUE, GL_BACK };
Dario Seyb's avatar
Dario Seyb committed
52

Dario Seyb's avatar
Dario Seyb committed
53 54 55 56 57
    skybox = m_sceneGraph->create();
    skybox.assign<Transform>();
    skybox.assign<Drawable>(skyboxGeom, skyboxMaterial, 0, skyboxPassId);
    skybox.assign<Light>(glm::vec4(1, 1, 1, 1), glm::vec3(1, 0, 0), false, LightType::POINT, skyboxPassId);
  }
Dario Seyb's avatar
Dario Seyb committed
58

Dario Seyb's avatar
Dario Seyb committed
59 60 61
  {
    auto mainPassId = m_renderer->getRenderPassId("Main"_sh);
    auto vaoSun = VertexArrayObjectCreator("uvsphere.obj").create();
Dario Seyb's avatar
Dario Seyb committed
62

Dario Seyb's avatar
Dario Seyb committed
63 64
    // load a texture:
    auto checkboardTexture = Texture2DFileManager::the()->get(Texture2DCreator("checkerboard.png"));
Dario Seyb's avatar
Dario Seyb committed
65

Dario Seyb's avatar
Dario Seyb committed
66 67 68 69
    // look up all shader files starting with 'PBR' and build a ShaderProgram from it:
    auto sunShader = ShaderProgramCreator("PBR")
      .attributeLocations(vaoSun->getAttributeLocations())
      .fragmentDataLocations(m_renderer->getGBufferLocations()).create();
Dario Seyb's avatar
Dario Seyb committed
70

Dario Seyb's avatar
Dario Seyb committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    // Create geometry objects that point to the previously initialized vaos
    Geometry geom1 = { vaoSun };
    geom1.vao->setMode(GL_PATCHES);

    // Create a material that uses the loaded shader program
    Material sunMaterial = { glm::vec4{ 1, 1, 1, 1 }, glm::vec4{ 2, 2, 1, 20 }, checkboardTexture, nullptr, nullptr, sunShader, false, RenderQueue::OPAQUE, GL_BACK };

    // Let's create a placeholder sun
    sun = m_sceneGraph->create();
    // Add a transform component to it so we are able to position it in space
    auto sunTransform = sun.assign<Transform>();
    // Add a Drawable component to it so the renderer has something to draw
    sun.assign<Drawable>(geom1, sunMaterial, 0, mainPassId);
    float scale = m_orbitals->solarRadius * m_orbitals->scaleFactor * 0.1;
    sunTransform->scale = glm::dvec3(scale);
    sunLight = sun.assign<Light>(glm::vec4(1, 1, 1, 3), glm::vec3(1, 0, 0), false, LightType::DIRECTIONAL, mainPassId);

    // create a planet! 
    // Mass in solar masses, Radius in solar radii, Eccentricity, Semimajor axis, Inclination, Ascending Node, Arg. of Periapsis, time at perihelion
    //																mass              radius            e         a        i          N          w
    earth = m_orbitals->addPlanet(sunTransform, "Earth", 0.000002988, 0.009153735632184, 0.016713, 1.000000, 0.0000000, 0.00000, 4.93533, 0);
  }
Dario Seyb's avatar
Dario Seyb committed
93

Dario Seyb's avatar
Dario Seyb committed
94
  {
Dario Seyb's avatar
Dario Seyb committed
95
    auto cockpitPassId = m_renderer->getRenderPassId("Cockpit"_sh);
Dario Seyb's avatar
Dario Seyb committed
96 97 98 99 100 101
    // create cockpit 
    auto vaoCockpit = VertexArrayObjectCreator("cockpit.obj").create();
    auto cockpitShader = ShaderProgramCreator("PBR")
      .attributeLocations(vaoCockpit->getAttributeLocations())
      .fragmentDataLocations(m_renderer->getGBufferLocations()).create();

102
    Material cockpitMaterial{ glm::vec4{0.4, 0.4, 0.4, 1}, glm::vec4{0, 0, 0, 1}, 
Dario Seyb's avatar
Dario Seyb committed
103 104 105 106
      Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_AlbedoTransparency.png")),
      Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_Normal.png")), 
      Texture2DFileManager::the()->get(Texture2DCreator("cockpit/cockpit_DefaultMaterial_SpecularSmoothness.png")),
      cockpitShader,
107
      true, 
Dario Seyb's avatar
Dario Seyb committed
108 109
      RenderQueue::OPAQUE, 
      GL_BACK };
110

Dario Seyb's avatar
Dario Seyb committed
111 112 113
    Geometry cockpitGeom{ vaoCockpit };
    cockpitGeom.vao->setMode(GL_PATCHES);
    cockpit = m_sceneGraph->create();
Dario Seyb's avatar
Dario Seyb committed
114
    auto cockpitDrawable = cockpit.assign<Drawable>(cockpitGeom, cockpitMaterial, 0, cockpitPassId);
Dario Seyb's avatar
Dario Seyb committed
115 116 117
    auto cockpitTransform = cockpit.assign<Transform>();
    cockpitTransform->position = glm::dvec3(0, 0, 0);
    cockpitDrawable->visible = true;
Dario Seyb's avatar
Dario Seyb committed
118
    auto cockpitLight = cockpit.assign<Light>(glm::vec4(1, 1, 1, 0.2), glm::vec3(1, 0, 0), false, LightType::POINT, cockpitPassId);
Dario Seyb's avatar
Dario Seyb committed
119

Dario Seyb's avatar
merged  
Dario Seyb committed
120 121
    cockpitSun = m_sceneGraph->create();
    cockpitSun.assign<Transform>();
Dario Seyb's avatar
Dario Seyb committed
122
    cockpitSunLight = cockpitSun.assign<Light>(glm::vec4(1, 1, 1, 3), glm::vec3(1, 0, 0), true, LightType::DIRECTIONAL, cockpitPassId);
Dario Seyb's avatar
merged  
Dario Seyb committed
123

Dario Seyb's avatar
Dario Seyb committed
124
    auto blinkButton = m_sceneGraph->create();
Dario Seyb's avatar
Dario Seyb committed
125
    blinkButton.assign<Light>(glm::vec4(1, 0.2, 0.2, 5), glm::vec3(1, 0, 0), false, LightType::POINT, cockpitPassId);
Dario Seyb's avatar
Dario Seyb committed
126 127 128 129 130
    auto transform = blinkButton.assign<Transform>();
    transform->parent = cockpitTransform;
    transform->position = { 0.7655, -0.4545 , -1.643 };

    blinkButton = m_sceneGraph->create();
Dario Seyb's avatar
Dario Seyb committed
131
    blinkButton.assign<Light>(glm::vec4(0, 0.2, 1.0, 5), glm::vec3(1, 0, 0), false, LightType::POINT, cockpitPassId);
Dario Seyb's avatar
Dario Seyb committed
132 133 134 135
    transform = blinkButton.assign<Transform>();
    transform->parent = cockpitTransform;
    transform->position = { -0.7655, -0.4545 , -1.643 };
  }
Dario Seyb's avatar
Dario Seyb committed
136

Dario Seyb's avatar
Dario Seyb committed
137 138
  m_events->subscribe<SimulateEvent>([this](const SimulateEvent& e) {
    sunLight->dir = -glm::normalize(m_player->getWorldPosition());
Dario Seyb's avatar
merged  
Dario Seyb committed
139
    cockpitSunLight->dir = glm::vec3(glm::dvec4(sunLight->dir, 0) * m_player->getRotation());
Dario Seyb's avatar
Dario Seyb committed
140 141
  });

Dario Seyb's avatar
Dario Seyb committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
  m_events->subscribe<KeyboardEvent>([this](const KeyboardEvent& e) {
    switch (e.originalEvent.key.keysym.scancode) {
      case SDL_SCANCODE_TAB:
	if (e.originalEvent.key.type == SDL_KEYDOWN) {
	  m_player->attachToParent(earth);
	  float r = earth.component<Transform>()->scale.x;
	  m_player->setPosition(glm::vec3(0, 0, r * 1.2));
      	  m_player->setRotation(glm::mat4());
	}
	break;
      default:
	break;
    }
  });

Dario Seyb's avatar
Dario Seyb committed
157 158 159 160 161 162 163 164 165 166 167 168
  // Subscribe to the UI drawing event.
  // This is called once per frame
  m_events->subscribe<"DrawUI"_sh>([this]() {

    ImGui::Begin("Camera Control", 0,
      ImGuiWindowFlags_::ImGuiWindowFlags_AlwaysAutoResize);

		float r;
    if (ImGui::Button("Sun/Global", glm::vec2(100, 20))) {
      // Reset the camera to sun coords
      m_player->attachToParent(sun);
			r = sun.component<Transform>()->scale.x;
David Gilbert's avatar
David Gilbert committed
169 170
      m_player->setPosition(glm::dvec3(0, 0, r * 1.2));
      m_player->setRotation(glm::dmat4());
Dario Seyb's avatar
Dario Seyb committed
171 172 173 174 175 176
    }


    if (ImGui::Button("Earth", glm::vec2(100, 20))) {
      m_player->attachToParent(earth);
			r = earth.component<Transform>()->scale.x;
David Gilbert's avatar
David Gilbert committed
177 178
			m_player->setPosition(glm::dvec3(0, 0, r * 1.2));
      m_player->setRotation(glm::dmat4());
Dario Seyb's avatar
Dario Seyb committed
179 180 181 182 183 184 185 186 187 188
    }

    ImGui::End();
  });

  return true;
}

void AtmosphereTestScene::shutdown() {
}