Browse Source

Add screen transition class

master
C. J. Howard 4 years ago
parent
commit
1346f0cac2
11 changed files with 468 additions and 192 deletions
  1. +13
    -4
      src/animation/animation.hpp
  2. +110
    -110
      src/animation/easings.hpp
  3. +88
    -0
      src/animation/screen-transition.cpp
  4. +65
    -0
      src/animation/screen-transition.hpp
  5. +74
    -49
      src/application.cpp
  6. +49
    -7
      src/application.hpp
  7. +23
    -7
      src/renderer/material-property.hpp
  8. +5
    -0
      src/renderer/passes/material-pass.cpp
  9. +1
    -0
      src/renderer/passes/material-pass.hpp
  10. +8
    -0
      src/state/play-state.cpp
  11. +32
    -15
      src/state/splash-state.cpp

+ 13
- 4
src/animation/animation.hpp View File

@ -161,6 +161,9 @@ public:
/// Creates an animation channel.
animation_channel(const animation_channel& other);
/// Assigns the contents of another channel to this channel.
animation_channel& operator=(const animation_channel& other);
/**
* Adds a keyframe to the animation.
*
@ -232,6 +235,13 @@ animation_channel::animation_channel(const animation_channel& other):
keyframes(other.keyframes)
{}
template <typename T>
animation_channel<T>& animation_channel<T>::operator=(const animation_channel& other)
{
id = other.id;
keyframes = other.keyframes;
}
template <typename T>
void animation_channel<T>::insert_keyframe(const keyframe& k)
{
@ -367,7 +377,6 @@ public:
/// @copydoc animation_base::get_duration() const
virtual double get_duration() const;
private:
std::unordered_map<int, channel> channels;
@ -449,9 +458,7 @@ void animation::advance(double dt)
}
}
else
{
stopped = true;
{
// Call frame callback for end frame
if (frame_callback != nullptr)
{
@ -465,6 +472,8 @@ void animation::advance(double dt)
}
}
stopped = true;
// Call end callback
if (end_callback)
{

+ 110
- 110
src/animation/easings.hpp View File

@ -54,231 +54,231 @@
#include <vmq/vmq.hpp>
#include <cmath>
template <typename T>
inline T ease_linear(const T& x, const T& y, float a)
template <typename T, typename S>
inline T ease_linear(const T& x, const T& y, S a)
{
return (y - x) * a + x;
}
template <typename T>
T ease_in_sine(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_sine(const T& x, const T& y, S a)
{
return -(y - x) * std::cos(a * vmq::half_pi<float>) + (y - x) + x;
return -(y - x) * std::cos(a * vmq::half_pi<S>) + (y - x) + x;
}
template <typename T>
T ease_out_sine(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_sine(const T& x, const T& y, S a)
{
return (y - x) * std::sin(a * vmq::half_pi<float>) + x;
return (y - x) * std::sin(a * vmq::half_pi<S>) + x;
}
template <typename T>
T ease_in_out_sine(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_sine(const T& x, const T& y, S a)
{
return -(y - x) * 0.5f * (std::cos(vmq::pi<float> * a) - 1.0f) + x;
return -(y - x) * S(0.5) * (std::cos(vmq::pi<S> * a) - S(1.0)) + x;
}
template <typename T>
T ease_in_quad(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_quad(const T& x, const T& y, S a)
{
return (y - x) * a * a + x;
}
template <typename T>
T ease_out_quad(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_quad(const T& x, const T& y, S a)
{
return -(y - x) * a * (a - 2.0f) + x;
return -(y - x) * a * (a - S(2.0)) + x;
}
template <typename T>
T ease_in_out_quad(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_quad(const T& x, const T& y, S a)
{
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * a * a + x;
return (y - x) * S(0.5) * a * a + x;
}
a -= 1.0f;
return -(y - x) * 0.5f * (a * (a - 2.0f) - 1.0f) + x;
a -= S(1.0);
return -(y - x) * S(0.5) * (a * (a - S(2.0)) - S(1.0)) + x;
}
template <typename T>
T ease_in_cubic(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_cubic(const T& x, const T& y, S a)
{
return (y - x) * a * a * a + x;
}
template <typename T>
T ease_out_cubic(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_cubic(const T& x, const T& y, S a)
{
a -= 1.0f;
return (y - x) * (a * a * a + 1.0f) + x;
a -= S(1.0);
return (y - x) * (a * a * a + S(1.0)) + x;
}
template <typename T>
T ease_in_out_cubic(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_cubic(const T& x, const T& y, S a)
{
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * a * a * a + x;
return (y - x) * S(0.5) * a * a * a + x;
}
a -= 2.0f;
return (y - x) * 0.5f * (a * a * a + 2.0f) + x;
a -= S(2.0);
return (y - x) * S(0.5) * (a * a * a + S(2.0)) + x;
}
template <typename T>
T ease_in_quart(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_quart(const T& x, const T& y, S a)
{
return (y - x) * a * a * a * a + x;
}
template <typename T>
T ease_out_quart(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_quart(const T& x, const T& y, S a)
{
a -= 1.0f;
return -(y - x) * (a * a * a * a - 1.0f) + x;
a -= S(1.0);
return -(y - x) * (a * a * a * a - S(1.0)) + x;
}
template <typename T>
T ease_in_out_quart(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_quart(const T& x, const T& y, S a)
{
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * a * a * a * a + x;
return (y - x) * S(0.5) * a * a * a * a + x;
}
a -= 2.0f;
return -(y - x) * 0.5f * (a * a * a * a - 2.0f) + x;
a -= S(2.0);
return -(y - x) * S(0.5) * (a * a * a * a - S(2.0)) + x;
}
template <typename T>
T ease_in_quint(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_quint(const T& x, const T& y, S a)
{
return (y - x) * a * a * a * a * a + x;
}
template <typename T>
T ease_out_quint(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_quint(const T& x, const T& y, S a)
{
a -= 1.0f;
return (y - x) * (a * a * a * a * a + 1.0f) + x;
a -= S(1.0);
return (y - x) * (a * a * a * a * a + S(1.0)) + x;
}
template <typename T>
T ease_in_out_quint(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_quint(const T& x, const T& y, S a)
{
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * a * a * a * a * a + x;
return (y - x) * S(0.5) * a * a * a * a * a + x;
}
a -= 2.0f;
return (y - x) * 0.5f * (a * a * a * a * a + 2.0f) + x;
a -= S(2.0);
return (y - x) * S(0.5) * (a * a * a * a * a + S(2.0)) + x;
}
template <typename T>
T ease_in_expo(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_expo(const T& x, const T& y, S a)
{
if (a == 0.0f)
if (a == S(0.0))
{
return x;
}
return (y - x) * std::pow(2.0f, 10.0f * (a - 1.0f)) + x;
return (y - x) * std::pow(S(2.0), S(10.0) * (a - S(1.0))) + x;
}
template <typename T>
T ease_out_expo(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_expo(const T& x, const T& y, S a)
{
if (a == 1.0f)
if (a == S(1.0))
{
return y;
}
return (y - x) * (-std::pow(2.0f, -10.0f * a) + 1.0f) + x;
return (y - x) * (-std::pow(S(2.0), -S(10.0) * a) + S(1.0)) + x;
}
template <typename T>
T ease_in_out_expo(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_expo(const T& x, const T& y, S a)
{
if (a == 0.0f)
if (a == S(0.0))
{
return x;
}
else if (a == 1.0f)
else if (a == S(1.0))
{
return y;
}
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * std::pow(2.0f, 10.0f * (a - 1.0f)) + x;
return (y - x) * S(0.5) * std::pow(S(2.0), S(10.0) * (a - S(1.0))) + x;
}
a -= 1.0f;
return (y - x) * 0.5f * (-std::pow(2.0f, -10.0f * a) + 2.0f) + x;
a -= S(1.0);
return (y - x) * S(0.5) * (-std::pow(S(2.0), -S(10.0) * a) + S(2.0)) + x;
}
template <typename T>
T ease_in_circ(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_circ(const T& x, const T& y, S a)
{
return -(y - x) * (std::sqrt(1.0f - a * a) - 1.0f) + x;
return -(y - x) * (std::sqrt(S(1.0) - a * a) - S(1.0)) + x;
}
template <typename T>
T ease_out_circ(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_circ(const T& x, const T& y, S a)
{
a -= 1.0f;
return (y - x) * std::sqrt(1.0f - a * a) + x;
a -= S(1.0);
return (y - x) * std::sqrt(S(1.0) - a * a) + x;
}
template <typename T>
T ease_in_out_circ(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_circ(const T& x, const T& y, S a)
{
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return -(y - x) * 0.5f * (std::sqrt(1.0f - a * a) - 1.0f) + x;
return -(y - x) * S(0.5) * (std::sqrt(S(1.0) - a * a) - S(1.0)) + x;
}
a -= 2.0f;
return (y - x) * 0.5f * (std::sqrt(1.0f - a * a) + 1.0f) + x;
a -= S(2.0);
return (y - x) * S(0.5) * (std::sqrt(S(1.0) - a * a) + S(1.0)) + x;
}
template <typename T>
T ease_in_back(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_back(const T& x, const T& y, S a)
{
const float s = 1.70158f;
return (y - x) * a * a * ((s + 1.0f) * a - s) + x;
const S s = S(1.70158);
return (y - x) * a * a * ((s + S(1.0)) * a - s) + x;
}
template <typename T>
T ease_out_back(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_out_back(const T& x, const T& y, S a)
{
const float s = 1.70158f;
a -= 1.0f;
return (y - x) * (a * a * ((s + 1.0f) * a + s) + 1.0f) + x;
const S s = S(1.70158);
a -= S(1.0);
return (y - x) * (a * a * ((s + S(1.0)) * a + s) + S(1.0)) + x;
}
template <typename T>
T ease_in_out_back(const T& x, const T& y, float a)
template <typename T, typename S>
T ease_in_out_back(const T& x, const T& y, S a)
{
const float s = 1.70158f * 1.525f;
const S s = S(1.70158) * S(1.525f);
a *= 2.0f;
if (a < 1.0f)
a *= S(2.0);
if (a < S(1.0))
{
return (y - x) * 0.5f * (a * a * ((s + 1.0f) * a - s)) + x;
return (y - x) * S(0.5) * (a * a * ((s + S(1.0)) * a - s)) + x;
}
a -= 2.0f;
return (y - x) * 0.5f * (a * a * ((s + 1.0f) * a + s) + 2.0f) + x;
a -= S(2.0);
return (y - x) * S(0.5) * (a * a * ((s + S(1.0)) * a + s) + S(2.0)) + x;
}
#endif // ANTKEEPER_EASINGS_HPP

+ 88
- 0
src/animation/screen-transition.cpp View File

@ -0,0 +1,88 @@
/*
* Copyright (C) 2020 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "screen-transition.hpp"
#include "renderer/material-flags.hpp"
#include <functional>
screen_transition::screen_transition()
{
// Setup material
material.set_flags(MATERIAL_FLAG_TRANSLUCENT | MATERIAL_FLAG_X_RAY);
progress = material.add_property<float>("progress");
// Setup billboard
billboard.set_material(&material);
billboard.set_active(false);
// Add single channel to transition animation
channel = animation.add_channel(0);
// Setup animation start callback to show transition billboard
animation.set_start_callback
(
std::bind(&scene_object_base::set_active, &billboard, true)
);
// Setup animation end callback to hide transition billboard
animation.set_end_callback
(
std::bind(&scene_object_base::set_active, &billboard, false)
);
// Setup animation frame callback to update transition progress material property
animation.set_frame_callback
(
[this](int channel, float progress)
{
this->progress->set_value(progress);
}
);
// Setup animation frame callback to update transition progress material property
animation.set_frame_callback
(
[this](int channel, float progress)
{
this->progress->set_value(progress);
}
);
}
void screen_transition::transition(float duration, bool reverse, ::animation<float>::interpolator_type interpolator)
{
float initial_state = (reverse) ? 1.0f : 0.0f;
float final_state = (reverse) ? 0.0f : 1.0f;
// Build transition animation
channel->remove_keyframes();
channel->insert_keyframe({0.0f, initial_state});
channel->insert_keyframe({duration, final_state});
// Set transition animation interpolator
animation.set_interpolator(interpolator);
// Update tweens
progress->set_value(initial_state);
material.update_tweens();
// Reset and play transition animation
animation.stop();
animation.play();
}

+ 65
- 0
src/animation/screen-transition.hpp View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_SCREEN_TRANSITION_HPP
#define ANTKEEPER_SCREEN_TRANSITION_HPP
#include "animation/animation.hpp"
#include "renderer/material.hpp"
#include "renderer/material-property.hpp"
#include "scene/billboard.hpp"
/**
* Encapsulates a shader-based animated screen transition.
*/
class screen_transition
{
public:
screen_transition();
void transition(float duration, bool reverse, animation<float>::interpolator_type interpolator);
::billboard* get_billboard();
::material* get_material();
::animation<float>* get_animation();
private:
::billboard billboard;
::material material;
material_property<float>* progress;
::animation<float> animation;
::animation<float>::channel* channel;
};
inline billboard* screen_transition::get_billboard()
{
return &billboard;
}
inline material* screen_transition::get_material()
{
return &material;
}
inline animation<float>* screen_transition::get_animation()
{
return &animation;
}
#endif // ANTKEEPER_SCREEN_TRANSITION_HPP

+ 74
- 49
src/application.cpp View File

@ -77,6 +77,8 @@
// Animation
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/screen-transition.hpp"
#include "animation/easings.hpp"
// Scene
#include "scene/billboard.hpp"
@ -101,24 +103,6 @@
// Entity components
#include "entity/components/cavity-component.hpp"
template <typename T>
inline T ease_linear(const T& x, const T& y, double a)
{
return (y - x) * a + x;
}
template <typename T>
T ease_in_quad(const T& x, const T& y, double a)
{
return (y - x) * a * a + x;
}
template <typename T>
T ease_out_quad(const T& x, const T& y, double a)
{
return -(y - x) * a * (a - 2.0f) + x;
}
using namespace vmq::operators;
application::application(int argc, char** argv):
@ -431,6 +415,7 @@ application::application(int argc, char** argv):
clear_pass = new ::clear_pass(rasterizer, framebuffer_hdr);
clear_pass->set_cleared_buffers(true, true, false);
sky_pass = new ::sky_pass(rasterizer, framebuffer_hdr, resource_manager);
sky_pass->set_enabled(false);
material_pass = new ::material_pass(rasterizer, framebuffer_hdr, resource_manager);
material_pass->set_fallback_material(fallback_material);
material_pass->set_time_tween(&time);
@ -474,8 +459,6 @@ application::application(int argc, char** argv):
shader_program* underworld_final_shader = resource_manager->load<shader_program>("underground-final.glsl");
underworld_final_pass = new simple_render_pass(rasterizer, &rasterizer->get_default_framebuffer(), underworld_final_shader);
underworld_final_pass->set_time_tween(&time);
underground_transition_property = underworld_final_pass->get_material()->add_property<float>("transition");
underground_transition_property->set_value(0.0f);
underground_color_texture_property = underworld_final_pass->get_material()->add_property<const texture_2d*>("color_texture");
underground_color_texture_property->set_value(framebuffer_hdr_color);
underworld_final_pass->get_material()->update_tweens();
@ -498,26 +481,8 @@ application::application(int argc, char** argv):
timeline.set_autoremove(true);
// Setup animation system
// ...
animator = new ::animator();
float radial_transition_time = 0.5f;
radial_transition_in = new animation<float>();
radial_transition_in->set_frame_callback([this](int channel, float value){this->underground_transition_property->set_value(value);});
radial_transition_in->set_interpolator(ease_in_quad<float>);
animation<float>::channel* channel = radial_transition_in->add_channel(0);
channel->insert_keyframe({0.0f, 0.0f});
channel->insert_keyframe({radial_transition_time, 1.0f});
animator->add_animation(radial_transition_in);
radial_transition_out = new animation<float>();
radial_transition_out->set_frame_callback([this](int channel, float value){this->underground_transition_property->set_value(value);});
radial_transition_out->set_interpolator(ease_out_quad<float>);
channel = radial_transition_out->add_channel(0);
channel->insert_keyframe({0.0f, 1.0f});
channel->insert_keyframe({radial_transition_time, 0.0f});
animator->add_animation(radial_transition_out);
// ECS
terrain_system = new ::terrain_system(ecs_registry, resource_manager);
terrain_system->set_patch_size(TERRAIN_PATCH_SIZE);
@ -673,21 +638,33 @@ application::application(int argc, char** argv):
{
if (this->active_scene == &this->overworld_scene)
{
// Switch to underworld
//this->overworld_camera.set_active(false);
this->underworld_camera.set_active(true);
this->active_scene = &this->underworld_scene;
this->radial_transition_out->stop();
this->radial_transition_in->play();
this->radial_transition_inner->transition(0.5f, false, ease_in_quad<float, double>);
auto switch_cameras = [this]()
{
this->overworld_camera.set_active(false);
this->underworld_camera.set_active(true);
this->fade_transition->transition(0.25f, true, ease_out_quad<float, double>);
};
float t = timeline.get_position();
this->timeline.add_cue({t + 0.5f, switch_cameras});
}
else
{
// Switch to overworld
//this->underworld_camera.set_active(false);
this->overworld_camera.set_active(true);
this->active_scene = &this->overworld_scene;
this->radial_transition_in->stop();
this->radial_transition_out->play();
this->fade_transition->transition(0.25f, false, ease_out_quad<float, double>);
auto switch_cameras = [this]()
{
this->overworld_camera.set_active(true);
this->underworld_camera.set_active(false);
this->radial_transition_inner->transition(0.5f, true, ease_out_quad<float, double>);
};
float t = timeline.get_position();
this->timeline.add_cue({t + 0.25f, switch_cameras});
}
});
@ -855,6 +832,50 @@ application::application(int argc, char** argv):
// Set overworld as active scene
active_scene = &overworld_scene;
// Setup UI
const texture_2d* splash_texture = resource_manager->load<texture_2d>("splash.png");
auto splash_dimensions = splash_texture->get_dimensions();
splash_billboard_material = new material();
splash_billboard_material->set_shader_program(resource_manager->load<shader_program>("ui-element-textured.glsl"));
splash_billboard_material->add_property<const texture_2d*>("background")->set_value(splash_texture);
splash_billboard_material->add_property<float4>("tint")->set_value(float4{1, 1, 1, 1});
splash_billboard_material->update_tweens();
splash_billboard = new billboard();
splash_billboard->set_material(splash_billboard_material);
splash_billboard->set_scale({(float)std::get<0>(splash_dimensions) * 0.5f, (float)std::get<1>(splash_dimensions) * 0.5f, 1.0f});
splash_billboard->set_translation({0.0f, 0.0f, 0.0f});
splash_billboard->update_tweens();
// Create fade transition
fade_transition = new screen_transition();
fade_transition->get_material()->set_shader_program(resource_manager->load<shader_program>("fade-transition.glsl"));
get_ui_scene()->add_object(fade_transition->get_billboard());
animator->add_animation(fade_transition->get_animation());
// Create inner radial transition
radial_transition_inner = new screen_transition();
radial_transition_inner->get_material()->set_shader_program(resource_manager->load<shader_program>("radial-transition-inner.glsl"));
get_ui_scene()->add_object(radial_transition_inner->get_billboard());
animator->add_animation(radial_transition_inner->get_animation());
// Create outer radial transition
radial_transition_outer = new screen_transition();
radial_transition_outer->get_material()->set_shader_program(resource_manager->load<shader_program>("radial-transition-outer.glsl"));
get_ui_scene()->add_object(radial_transition_outer->get_billboard());
animator->add_animation(radial_transition_outer->get_animation());
// Determine initial state
initial_state = &splash_state;
std::string no_splash_flag = "--skip-splash";
for (int i = 0; i < argc; ++i)
{
if (no_splash_flag == argv[i])
{
initial_state = &play_state;
break;
}
}
}
application::~application()
@ -876,7 +897,7 @@ void application::close(int status)
int application::execute()
{
// Enter inital state
state_machine.change_state(play_state);
state_machine.change_state(*initial_state);
// Perform initial update
update(0.0, 0.0);
@ -1147,3 +1168,7 @@ void application::save_image(const std::string& filename, int w, int h, const un
delete[] pixels;
}
scene* application::get_ui_scene()
{
return ui_system->get_scene();
}

+ 49
- 7
src/application.hpp View File

@ -63,6 +63,7 @@
// Animation
#include "animation/timeline.hpp"
#include "animation/tween.hpp"
#include "animation/animation.hpp"
// Misc
#include "state/fsm.hpp"
@ -94,9 +95,14 @@
class bloom_pass;
class final_pass;
class simple_render_pass;
template <class T>
class material_property;
// Animation
class animator;
template <class T>
class animation;
class screen_transition;
// Systems
class behavior_system;
@ -114,11 +120,8 @@
class control_system;
class ui_system;
template <class T>
class material_property;
template <class T>
class animation;
// Scene
class billboard;
//}
class application
@ -171,6 +174,16 @@ public:
scene& get_scene();
void take_screenshot() const;
// UI
scene* get_ui_scene();
billboard* get_splash_billboard();
::sky_pass* get_sky_pass();
screen_transition* get_fade_transition();
screen_transition* get_radial_transition_inner();
screen_transition* get_radial_transition_outer();
private:
void update(double t, double dt);
@ -261,7 +274,6 @@ private:
::clear_pass* underworld_clear_pass;
::material_pass* underworld_material_pass;
simple_render_pass* underworld_final_pass;
material_property<float>* underground_transition_property;
material_property<const texture_2d*>* underground_color_texture_property;
compositor underworld_compositor;
@ -273,6 +285,7 @@ private:
fsm::state title_state;
fsm::state play_state;
fsm::state pause_state;
fsm::state* initial_state;
// Frame timing
frame_scheduler frame_scheduler;
@ -326,9 +339,14 @@ private:
compositor ui_compositor;
::clear_pass* ui_clear_pass;
::material_pass* ui_material_pass;
billboard* splash_billboard;
material* splash_billboard_material;
// Animation
tween<float3> focal_point_tween;
screen_transition* fade_transition;
screen_transition* radial_transition_inner;
screen_transition* radial_transition_outer;
};
inline logger* application::get_logger()
@ -421,5 +439,29 @@ inline scene& application::get_scene()
return overworld_scene;
}
#endif // ANTKEEPER_APPLICATION_HPP
inline billboard* application::get_splash_billboard()
{
return splash_billboard;
}
inline sky_pass* application::get_sky_pass()
{
return sky_pass;
}
inline screen_transition* application::get_fade_transition()
{
return fade_transition;
}
inline screen_transition* application::get_radial_transition_inner()
{
return radial_transition_inner;
}
inline screen_transition* application::get_radial_transition_outer()
{
return radial_transition_outer;
}
#endif // ANTKEEPER_APPLICATION_HPP

+ 23
- 7
src/renderer/material-property.hpp View File

@ -127,7 +127,6 @@ public:
* @param value Value to set.
*/
void set_value(const T& value);
void set_val(const T& value);
/**
* Sets the value of a single element in this array property.
@ -145,6 +144,17 @@ public:
* @param count Number of elements to set.
*/
void set_values(std::size_t index, const T* values, std::size_t count);
/// Returns the value of the first element in this property.
const T& get_value() const;
/**
* Returns the value of the first element in this property.
*
* @param index Index of an array element.
* @return Value of the element at the specified index.
*/
const T& get_value(std::size_t index) const;
/// @copydoc material_property_base::get_data_type() const
virtual shader_variable_type get_data_type() const;
@ -210,12 +220,6 @@ void material_property::set_value(const T& value)
values[0][1] = value;
}
template <class T>
void material_property<T>::set_val(const T& value)
{
values[0][1] = value;
}
template <class T>
void material_property<T>::set_value(std::size_t index, const T& value)
{
@ -231,6 +235,18 @@ void material_property::set_values(std::size_t index, const T* values, std::s
}
}
template <class T>
inline const T& material_property<T>::get_value() const
{
return values[0][1];
}
template <class T>
inline const T& material_property<T>::get_value(std::size_t index) const
{
return values[index][1];
}
template <>
inline shader_variable_type material_property<bool>::get_data_type() const
{

+ 5
- 0
src/renderer/passes/material-pass.cpp View File

@ -116,6 +116,8 @@ void material_pass::render(render_context* context) const
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))};
float time = (time_tween) ? time_tween->interpolate(context->alpha) : 0.0f;
float3 focal_point = (focal_point_tween) ? focal_point_tween->interpolate(context->alpha) : float3{0, 0, 0};
float4x4 view = context->camera->get_view_tween().interpolate(context->alpha);
@ -356,6 +358,8 @@ void material_pass::render(render_context* context) const
// Upload context-dependent shader parameters
if (parameters->time)
parameters->time->upload(time);
if (parameters->resolution)
parameters->resolution->upload(resolution);
if (parameters->view)
parameters->view->upload(view);
if (parameters->view_projection)
@ -452,6 +456,7 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const shad
// Connect inputs
parameters->time = program->get_input("time");
parameters->resolution = program->get_input("resolution");
parameters->model = program->get_input("model");
parameters->view = program->get_input("view");
parameters->projection = program->get_input("projection");

+ 1
- 0
src/renderer/passes/material-pass.hpp View File

@ -60,6 +60,7 @@ private:
struct parameter_set
{
const shader_input* time;
const shader_input* resolution;
const shader_input* model;
const shader_input* view;
const shader_input* projection;

+ 8
- 0
src/state/play-state.cpp View File

@ -20,10 +20,12 @@
#include "application-states.hpp"
#include "configuration.hpp"
#include "application.hpp"
#include "animation/screen-transition.hpp"
#include "scene/model-instance.hpp"
#include "resources/resource-manager.hpp"
#include "renderer/model.hpp"
#include "renderer/material.hpp"
#include "renderer/passes/sky-pass.hpp"
#include "systems/control-system.hpp"
#include "entity/components/model-component.hpp"
#include "entity/components/transform-component.hpp"
@ -37,6 +39,7 @@
#include "math.hpp"
#include "geometry/mesh-accelerator.hpp"
#include "behavior/ebt.hpp"
#include "animation/easings.hpp"
#include <iostream>
using namespace vmq::operators;
@ -46,6 +49,8 @@ void enter_play_state(application* app)
logger* logger = app->get_logger();
logger->push_task("Entering play state");
// Enable sky pass
app->get_sky_pass()->set_enabled(true);
resource_manager* resource_manager = app->get_resource_manager();
entt::registry& ecs_registry = app->get_ecs_registry();
@ -226,6 +231,9 @@ void enter_play_state(application* app)
control_system->update(0.0f);
control_system->set_nest(nest);
orbit_cam->update(0.0f);
// Start fade in
app->get_fade_transition()->transition(1.0f, true, ease_in_quad<float, double>);
logger->pop_task(EXIT_SUCCESS);
}

+ 32
- 15
src/state/splash-state.cpp View File

@ -19,6 +19,14 @@
#include "application-states.hpp"
#include "application.hpp"
#include "scene/billboard.hpp"
#include "renderer/material.hpp"
#include "renderer/material-property.hpp"
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/easings.hpp"
#include "animation/screen-transition.hpp"
#include "renderer/passes/sky-pass.hpp"
#include <functional>
#include <iostream>
@ -28,34 +36,40 @@ void enter_splash_state(application* app)
logger* logger = app->get_logger();
logger->push_task("Entering splash state");
auto fade_in = [logger]()
{
logger->log("cue logo fade-in\n");
};
// Disable sky pass
app->get_sky_pass()->set_enabled(false);
// Add splash billboard to UI scene
app->get_ui_scene()->add_object(app->get_splash_billboard());
// Setup timing
const float splash_fade_in_duration = 0.5f;
const float splash_hang_duration = 2.0f;
const float splash_fade_out_duration = 0.5f;
auto fade_out = [logger]()
// Start fade in
app->get_fade_transition()->transition(splash_fade_in_duration, true, ease_in_quad<float, double>);
// Crate fade out function
auto fade_out = [app, splash_fade_out_duration]()
{
logger->log("cue logo fade-out\n");
app->get_fade_transition()->transition(splash_fade_out_duration, false, ease_out_quad<float, double>);
};
// Create change state function
auto change_state = [app]()
{
app->get_state_machine()->change_state(app->get_title_state());
app->get_state_machine()->change_state(app->get_play_state());
};
// Get timeline
// Schedule fade out and change state events
timeline* timeline = app->get_timeline();
// Create splash sequence
float t = timeline->get_position();
timeline::sequence splash_sequence =
{
{t + 0.0f, fade_in},
{t + 3.0f, fade_out},
{t + 8.0f, change_state}
{t + splash_fade_in_duration + splash_hang_duration, fade_out},
{t + splash_fade_in_duration + splash_hang_duration + splash_fade_out_duration, change_state}
};
// Add splash sequence to timeline
timeline->add_sequence(splash_sequence);
logger->pop_task(EXIT_SUCCESS);
@ -66,5 +80,8 @@ void exit_splash_state(application* app)
logger* logger = app->get_logger();
logger->push_task("Exiting splash state");
// Remove splash billboard from UI scene
app->get_ui_scene()->remove_object(app->get_splash_billboard());
logger->pop_task(EXIT_SUCCESS);
}

Loading…
Cancel
Save