#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(); auto vaoSun = VertexArrayObjectCreator("uvsphere.obj").create(); // load a texture: auto checkboardTexture = Texture2DFileManager::the()->get(Texture2DCreator("checkerboard.png")); // 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(); // 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 }; // 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(); // Add a Drawable component to it so the renderer has something to draw sun.assign(geom1, sunMaterial); float scale = m_orbitals->solarRadius * m_orbitals->scaleFactor * 0.1; sunTransform->scale = glm::dvec3(scale); sunLight = sun.assign(glm::vec4(1, 1, 1, 3), glm::vec3(1, 0, 0), false, LightType::DIRECTIONAL); // 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); { // create cockpit auto vaoCockpit = VertexArrayObjectCreator("cockpit.obj").create(); auto cockpitShader = ShaderProgramCreator("PBR") .attributeLocations(vaoCockpit->getAttributeLocations()) .fragmentDataLocations(m_renderer->getGBufferLocations()).create(); Material cockpitMaterial{ glm::vec4{0.4, 0.4, 0.4, 1}, glm::vec4{0, 0, 0, 1}, 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, true, RenderQueue::OPAQUE }; Geometry cockpitGeom{ vaoCockpit }; cockpitGeom.vao->setMode(GL_PATCHES); cockpit = m_sceneGraph->create(); auto cockpitDrawable = cockpit.assign(cockpitGeom, cockpitMaterial); auto cockpitTransform = cockpit.assign(); cockpitTransform->position = glm::dvec3(0, 0, 0); cockpitDrawable->renderPassIndex = 1; cockpitDrawable->visible = true; auto cockpitLight = cockpit.assign(glm::vec4(1, 1, 1, 0.2), glm::vec3(1, 0, 0), false, LightType::POINT, 1); auto blinkButton = m_sceneGraph->create(); blinkButton.assign(glm::vec4(1, 0.2, 0.2, 5), glm::vec3(1, 0, 0), false, LightType::POINT, 1); auto transform = blinkButton.assign(); transform->parent = cockpitTransform; transform->position = { 0.7655, -0.4545 , -1.643 }; blinkButton = m_sceneGraph->create(); blinkButton.assign(glm::vec4(0, 0.2, 1.0, 5), glm::vec3(1, 0, 0), false, LightType::POINT, 1); transform = blinkButton.assign(); transform->parent = cockpitTransform; transform->position = { -0.7655, -0.4545 , -1.643 }; } m_events->subscribe([this](const SimulateEvent& e) { sunLight->dir = -glm::normalize(m_player->getWorldPosition()); }); m_events->subscribe([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()->scale.x; m_player->setPosition(glm::vec3(0, 0, r * 1.2)); m_player->setRotation(glm::mat4()); } break; default: break; } }); // 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()->scale.x; m_player->setPosition(glm::dvec3(0, 0, r * 1.2)); m_player->setRotation(glm::dmat4()); } if (ImGui::Button("Earth", glm::vec2(100, 20))) { m_player->attachToParent(earth); r = earth.component()->scale.x; m_player->setPosition(glm::dvec3(0, 0, r * 1.2)); m_player->setRotation(glm::dmat4()); } ImGui::End(); }); return true; } void AtmosphereTestScene::shutdown() { }