Browse Source

Add simple_render_pass class and add task support to logger

master
C. J. Howard 3 years ago
parent
commit
7195ca0ec6
22 changed files with 599 additions and 137 deletions
  1. +3
    -1
      CMakeLists.txt
  2. +0
    -6
      src/animation/animation.cpp
  3. +12
    -12
      src/animation/animation.hpp
  4. +26
    -0
      src/animation/animator.cpp
  5. +35
    -0
      src/animation/animator.hpp
  6. +119
    -70
      src/application.cpp
  7. +41
    -16
      src/application.hpp
  8. +42
    -1
      src/debug/logger.cpp
  9. +20
    -0
      src/debug/logger.hpp
  10. +2
    -2
      src/nest.cpp
  11. +6
    -0
      src/renderer/renderer.cpp
  12. +6
    -0
      src/renderer/renderer.hpp
  13. +115
    -0
      src/renderer/simple-render-pass.cpp
  14. +74
    -0
      src/renderer/simple-render-pass.hpp
  15. +7
    -1
      src/resources/resource-manager.cpp
  16. +25
    -0
      src/resources/resource-manager.hpp
  17. +4
    -4
      src/state/loading-state.cpp
  18. +7
    -5
      src/state/play-state.cpp
  19. +30
    -10
      src/state/splash-state.cpp
  20. +10
    -9
      src/state/title-state.cpp
  21. +10
    -0
      src/systems/ui-system.cpp
  22. +5
    -0
      src/systems/ui-system.hpp

+ 3
- 1
CMakeLists.txt View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.7)
option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING})
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)
# Set compiler flags
if(CMAKE_COMPILER_IS_GNUCC)
@ -15,6 +15,7 @@ elseif(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} /Ox")
endif()
# Find dependency packages
find_package(vmq REQUIRED CONFIG)
find_package(dr_wav REQUIRED CONFIG)
@ -119,3 +120,4 @@ elseif(PACKAGE_PLATFORM MATCHES "win")
endif()
install(FILES ${OPENAL_DLL} DESTINATION .)
endif()

+ 0
- 6
src/animation/animation.cpp View File

@ -21,9 +21,3 @@
void animation_base::animate(float dt)
{}
void animator::animate(float dt)
{
}

+ 12
- 12
src/animation/animation.hpp View File

@ -22,6 +22,18 @@
#include <functional>
class animation_channel_base
{
};
template <typename T>
class animation_channel: public animation_channel_base
{
public:
void insert_keyframe(float position, const T& value);
};
class animation_base
{
public:
@ -49,16 +61,4 @@ class skeletal_animation: public animation
};
class animator
{
public:
/**
* Progresses all active animations by @p dt.
*
* @param dt Delta time by which the animations will be progressed.
*/
void animate(float dt);
};
#endif // ANTKEEPER_ANIMATION_HPP

+ 26
- 0
src/animation/animator.cpp View File

@ -0,0 +1,26 @@
/*
* 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 "animator.hpp"
void animator::animate(float dt)
{
}

+ 35
- 0
src/animation/animator.hpp View File

@ -0,0 +1,35 @@
/*
* 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_ANIMATOR_HPP
#define ANTKEEPER_ANIMATOR_HPP
class animator
{
public:
/**
* Progresses all active animations by @p dt.
*
* @param dt Delta time by which the animations will be progressed.
*/
void animate(float dt);
};
#endif // ANTKEEPER_ANIMATOR_HPP

+ 119
- 70
src/application.cpp View File

@ -62,6 +62,7 @@
#include "rasterizer/texture-filter.hpp"
// Renderer
#include "renderer/simple-render-pass.hpp"
#include "renderer/passes/shadow-map-pass.hpp"
#include "renderer/passes/sky-pass.hpp"
#include "renderer/passes/clear-pass.hpp"
@ -70,6 +71,10 @@
#include "renderer/passes/final-pass.hpp"
#include "renderer/vertex-attributes.hpp"
#include "renderer/material-flags.hpp"
#include "renderer/material-property.hpp"
// Animation
#include "animation/animator.hpp"
// Scene
#include "scene/billboard.hpp"
@ -148,20 +153,21 @@ application::application(int argc, char** argv):
{
if (!path_exists(path))
{
logger.log("Creating directory \"" + path + "\"... ");
int create_path_task = logger.open_task("Creating directory \"" + path + "\"");
if (create_directory(path))
{
logger.success("success\n");
logger.close_task(create_path_task, EXIT_SUCCESS);
}
else
{
logger.error("failed\n");
logger.close_task(create_path_task, EXIT_FAILURE);
}
}
}
// Setup resource manager
resource_manager = new ::resource_manager();
resource_manager->set_logger(&logger);
// Include resource search paths in order of priority
resource_manager->include(config_path);
@ -188,26 +194,26 @@ application::application(int argc, char** argv):
logger.log("Linking against SDL " + sdl_linked_version_string + "\n");
// Init SDL
logger.log("Initializing SDL... ");
int sdl_init_task = logger.open_task("Initializing SDL");
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
logger.log("failed\n");
logger.close_task(sdl_init_task, EXIT_FAILURE);
throw std::runtime_error("Failed to initialize SDL");
}
else
{
logger.log("success\n");
logger.close_task(sdl_init_task, EXIT_SUCCESS);
}
// Load default OpenGL library
logger.log("Loading OpenGL library... ");
int load_gl_task = logger.open_task("Loading OpenGL library");
if (SDL_GL_LoadLibrary(nullptr) != 0)
{
logger.log("failed\n");
logger.close_task(load_gl_task, EXIT_FAILURE);
}
else
{
logger.log("success\n");
logger.close_task(load_gl_task, EXIT_SUCCESS);
}
// Set window creation hints
@ -231,61 +237,71 @@ application::application(int argc, char** argv):
int window_width = 1920;
int window_height = 1080;
fullscreen = true;
window_width = 1280;
window_height = 720;
fullscreen = false;
viewport = {0.0f, 0.0f, static_cast<float>(window_width), static_cast<float>(window_height)};
int window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN;
if (fullscreen)
{
window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
// Create window
logger.log("Creating " + std::to_string(window_width) + "x" + std::to_string(window_height) + " window... ");
int window_creation_task = logger.open_task("Creating " + std::to_string(window_width) + "x" + std::to_string(window_height) + " window");
window = SDL_CreateWindow
(
"Antkeeper",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
window_width, window_height,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_FULLSCREEN_DESKTOP
window_flags
);
if (!window)
{
logger.error("failed\n");
logger.close_task(window_creation_task, EXIT_FAILURE);
throw std::runtime_error("Failed to create SDL window");
}
else
{
logger.success("success\n");
logger.close_task(window_creation_task, EXIT_SUCCESS);
}
// Create OpenGL context
logger.log("Creating OpenGL 3.3 context... ");
int create_gl_context_task = logger.open_task("Creating OpenGL 3.3 context");
context = SDL_GL_CreateContext(window);
if (!context)
{
logger.error("failed\n");
logger.close_task(create_gl_context_task, EXIT_FAILURE);
throw std::runtime_error("Failed to create OpenGL context");
}
else
{
logger.success("success\n");
logger.close_task(create_gl_context_task, EXIT_SUCCESS);
}
// Load OpenGL functions via GLAD
logger.log("Loading OpenGL functions... ");
int load_gl_functions_task = logger.open_task("Loading OpenGL functions");
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
{
logger.error("failed\n");
logger.close_task(load_gl_functions_task, EXIT_FAILURE);
}
else
{
logger.success("success\n");
logger.close_task(load_gl_functions_task, EXIT_SUCCESS);
}
// Set v-sync mode
int swap_interval = 1;
logger.log((swap_interval) ? "Enabling v-sync... " : "Disabling v-sync... ");
int set_vsync_task = logger.open_task((swap_interval) ? "Enabling v-sync" : "Disabling v-sync");
if (SDL_GL_SetSwapInterval(swap_interval) != 0)
{
logger.error("failed\n");
logger.close_task(set_vsync_task, EXIT_FAILURE);
}
else
{
logger.success("success\n");
logger.close_task(set_vsync_task, EXIT_SUCCESS);
}
// Setup rasterizer
@ -303,27 +319,27 @@ application::application(int argc, char** argv):
SDL_ShowCursor(SDL_DISABLE);
// Init SDL joystick and game controller subsystems
logger.log("Initializing SDL Joystick and Game Controller subsystems... ");
int init_sdl_subsystems_task = logger.open_task("Initializing SDL Joystick and Game Controller subsystems");
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) != 0)
{
logger.log("failed\n");
logger.close_task(init_sdl_subsystems_task, EXIT_FAILURE);
throw std::runtime_error("Failed to initialize SDL Joystick or Game Controller subsystems");
}
else
{
logger.success("success\n");
logger.close_task(init_sdl_subsystems_task, EXIT_SUCCESS);
}
// Load SDL game controller mappings
logger.log("Loading SDL game controller mappings from database... ");
int load_controller_db_task = logger.open_task("Loading SDL game controller mappings from database");
std::string gamecontrollerdb_path = data_path + "controls/gamecontrollerdb.txt";
if (SDL_GameControllerAddMappingsFromFile(gamecontrollerdb_path.c_str()) == -1)
{
logger.error("failed\n");
logger.close_task(load_controller_db_task, EXIT_FAILURE);
}
else
{
logger.success("success\n");
logger.close_task(load_controller_db_task, EXIT_SUCCESS);
}
// Setup billboard VAO
@ -355,7 +371,6 @@ application::application(int argc, char** argv):
// Load fallback material
fallback_material = resource_manager->load<material>("fallback.mtl");
// Create shadow map depth texture and framebuffer
shadow_map_resolution = 4096;
shadow_map_depth_texture = new texture_2d(shadow_map_resolution, shadow_map_resolution, pixel_type::float_32, pixel_format::d);
@ -388,7 +403,7 @@ application::application(int argc, char** argv):
framebuffer_bloom = new framebuffer(bloom_width, bloom_height);
framebuffer_bloom->attach(framebuffer_attachment_type::color, bloom_texture);
// Setup default compositor
// Setup overworld passes
shadow_map_clear_pass = new ::clear_pass(rasterizer, shadow_map_framebuffer);
shadow_map_clear_pass->set_cleared_buffers(false, true, false);
shadow_map_pass = new ::shadow_map_pass(rasterizer, shadow_map_framebuffer, resource_manager);
@ -402,35 +417,65 @@ application::application(int argc, char** argv):
material_pass->set_focal_point_tween(&focal_point_tween);
material_pass->shadow_map_pass = shadow_map_pass;
material_pass->shadow_map = shadow_map_depth_texture;
bloom_pass = new ::bloom_pass(rasterizer, framebuffer_bloom, resource_manager);
bloom_pass->set_source_texture(framebuffer_hdr_color);
bloom_pass->set_brightness_threshold(1.0f);
bloom_pass->set_blur_iterations(4);
bloom_pass->set_enabled(false);
final_pass = new ::final_pass(rasterizer, &rasterizer->get_default_framebuffer(), resource_manager);
final_pass->set_color_texture(framebuffer_hdr_color);
final_pass->set_bloom_texture(bloom_texture);
default_compositor.add_pass(shadow_map_clear_pass);
default_compositor.add_pass(shadow_map_pass);
default_compositor.add_pass(clear_pass);
default_compositor.add_pass(sky_pass);
default_compositor.add_pass(material_pass);
default_compositor.add_pass(bloom_pass);
default_compositor.add_pass(final_pass);
// Setup overworld compositor
overworld_compositor.add_pass(shadow_map_clear_pass);
overworld_compositor.add_pass(shadow_map_pass);
overworld_compositor.add_pass(clear_pass);
overworld_compositor.add_pass(sky_pass);
overworld_compositor.add_pass(material_pass);
overworld_compositor.add_pass(bloom_pass);
overworld_compositor.add_pass(final_pass);
// Setup overworld camera
overworld_camera.set_perspective(45.0f * vmq::pi<float> / 180.0f, (float)window_width / (float)window_height, 0.1f, 1000.0f);
overworld_camera.set_compositor(&overworld_compositor);
overworld_camera.set_composite_index(0);
overworld_camera.set_active(true);
// Setup underworld passes
underworld_clear_pass = new ::clear_pass(rasterizer, framebuffer_hdr);
underworld_clear_pass->set_cleared_buffers(true, true, false);
underworld_material_pass = new ::material_pass(rasterizer, framebuffer_hdr, resource_manager);
underworld_material_pass->set_fallback_material(fallback_material);
underworld_material_pass->set_time_tween(&time);
underworld_material_pass->set_focal_point_tween(&focal_point_tween);
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_color_texture_property = underworld_final_pass->get_material()->add_property<const texture_2d*>("color_texture");
underground_color_texture_property->set_value(framebuffer_hdr_color);
// Setup underworld compositor
underworld_compositor.add_pass(underworld_clear_pass);
underworld_compositor.add_pass(underworld_material_pass);
underworld_compositor.add_pass(underworld_final_pass);
// Setup default camera
default_camera.set_perspective(45.0f * vmq::pi<float> / 180.0f, (float)window_width / (float)window_height, 0.1f, 1000.0f);
default_camera.set_compositor(&default_compositor);
default_camera.set_composite_index(1);
// Setup underworld camera
underworld_camera.set_perspective(45.0f * vmq::pi<float> / 180.0f, (float)window_width / (float)window_height, 0.1f, 1000.0f);
underworld_camera.look_at({0, 50, 0}, {0, 0, 0}, {0, 0, -1});
underworld_camera.set_compositor(&underworld_compositor);
underworld_camera.set_composite_index(0);
underworld_camera.set_active(false);
// Setup timeline system
timeline.set_autoremove(true);
// Setup animation system
// ...
animator = new ::animator();
// ECS
terrain_system = new ::terrain_system(ecs_registry, resource_manager);
@ -444,7 +489,7 @@ application::application(int argc, char** argv):
tool_system = new ::tool_system(ecs_registry);
tool_system->set_camera(&default_camera);
tool_system->set_camera(&overworld_camera);
tool_system->set_orbit_cam(&orbit_cam);
tool_system->set_viewport(viewport);
camera_system = new ::camera_system(ecs_registry);
@ -479,14 +524,14 @@ application::application(int argc, char** argv):
systems.push_back([this](double t, double dt){
this->subterrain_light.set_translation(orbit_cam.get_focal_point());
this->lantern.set_translation(orbit_cam.get_focal_point());
this->spotlight.set_transform(default_camera.get_transform());
this->spotlight.set_transform(overworld_camera.get_transform());
this->focal_point_tween[1] = orbit_cam.get_focal_point();
});
systems.push_back([this](double t, double dt){ this->ui_system->update(dt); });
systems.push_back(std::bind(&tool_system::update, tool_system, std::placeholders::_1, std::placeholders::_2));
systems.push_back(std::bind(&model_system::update, model_system, std::placeholders::_1, std::placeholders::_2));
systems.push_back([this](double t, double dt){ this->animator.animate(dt); });
systems.push_back([this](double t, double dt){ this->animator->animate(dt); });
systems.push_back([this](double t, double dt){ this->application_controls.update(); this->menu_controls.update(); this->camera_controls->update(); });
// Setup FSM states
@ -533,7 +578,7 @@ application::application(int argc, char** argv):
// Setup input event routing
input_event_router.set_event_dispatcher(&event_dispatcher);
input_mapper.set_event_dispatcher(&event_dispatcher);
// Setup input devices
keyboard.set_event_dispatcher(&event_dispatcher);
mouse.set_event_dispatcher(&event_dispatcher);
@ -553,7 +598,7 @@ application::application(int argc, char** argv):
menu_controls.add_control(&menu_back_control);
menu_controls.add_control(&menu_select_control);
orbit_cam.attach(&default_camera);
orbit_cam.attach(&overworld_camera);
control_system = new ::control_system();
control_system->set_orbit_cam(&orbit_cam);
control_system->set_viewport(viewport);
@ -585,14 +630,20 @@ application::application(int argc, char** argv):
control_system->get_toggle_view_control()->set_activated_callback(
[this]()
{
this->active_scene->remove_object(&this->default_camera);
this->active_scene = (this->active_scene == &this->overworld_scene) ? &this->underworld_scene : &this->overworld_scene;
this->active_scene->add_object(&this->default_camera);
if (this->active_scene == &this->overworld_scene)
this->sky_pass->set_enabled(true);
{
// Switch to underworld
//this->overworld_camera.set_active(false);
this->underworld_camera.set_active(true);
this->active_scene = &this->underworld_scene;
}
else
this->sky_pass->set_enabled(false);
{
// Switch to overworld
this->underworld_camera.set_active(false);
this->overworld_camera.set_active(true);
this->active_scene = &this->overworld_scene;
}
});
input_event_router.add_mapping(game_controller_axis_mapping(control_system->get_move_forward_control(), nullptr, game_controller_axis::left_y, true));
@ -738,32 +789,27 @@ application::application(int argc, char** argv):
// Setup overworld scene
overworld_scene.add_object(&default_camera);
overworld_scene.add_object(&overworld_camera);
overworld_scene.add_object(&sun_indirect);
overworld_scene.add_object(&sun_direct);
overworld_scene.add_object(&spotlight);
overworld_scene.add_object(&cloud);
overworld_scene.add_object(arrow_billboard);
underworld_scene.add_object(portal_billboard);
model_instance* larva = new model_instance(resource_manager->load<model>("larva.obj"));
underworld_scene.add_object(larva);
model_instance* samara = new model_instance(resource_manager->load<model>("samara.obj"));
samara->set_translation({2, -1, 0});
underworld_scene.add_object(samara);
// Setup underworld scene
underworld_scene.add_object(&underworld_camera);
underworld_scene.add_object(&underworld_ambient_light);
//underworld_scene.add_object(&darkness_volume);
underworld_scene.add_object(&lantern);
underworld_scene.add_object(&subterrain_light);
underworld_scene.add_object(portal_billboard);
//model_instance* larva = new model_instance(resource_manager->load<model>("larva.obj"));
//underworld_scene.add_object(larva);
model_instance* flashlight = new model_instance(resource_manager->load<model>("flashlight.obj"));
underworld_scene.add_object(flashlight);
// Set overworld as active scene
active_scene = &overworld_scene;
}
application::~application()
@ -785,7 +831,7 @@ void application::close(int status)
int application::execute()
{
// Enter inital state
state_machine.change_state(play_state);
state_machine.change_state(splash_state);
// Perform initial update
update(0.0, 0.0);
@ -833,7 +879,9 @@ void application::render(double alpha)
std::cout << performance_sampler.mean_frame_duration() * 1000.0 << std::endl;
*/
renderer.render(alpha, *active_scene);
renderer.render(alpha, overworld_scene);
renderer.render(alpha, underworld_scene);
//renderer.render(alpha, *active_scene);
renderer.render(alpha, *ui_system->get_scene());
SDL_GL_SwapWindow(window);
@ -1022,7 +1070,8 @@ void application::window_resized()
viewport = {0.0f, 0.0f, static_cast<float>(width), static_cast<float>(height)};
rasterizer->window_resized(width, height);
default_camera.set_perspective(default_camera.get_fov(), aspect_ratio, default_camera.get_clip_near(), default_camera.get_clip_far());
overworld_camera.set_perspective(overworld_camera.get_fov(), aspect_ratio, overworld_camera.get_clip_near(), overworld_camera.get_clip_far());
underworld_camera.set_perspective(underworld_camera.get_fov(), aspect_ratio, underworld_camera.get_clip_near(), underworld_camera.get_clip_far());
control_system->set_viewport(viewport);
camera_system->set_viewport(viewport);
tool_system->set_viewport(viewport);

+ 41
- 16
src/application.hpp View File

@ -61,7 +61,6 @@
// Animation
#include "animation/timeline.hpp"
#include "animation/animation.hpp"
#include "animation/tween.hpp"
// Misc
@ -93,6 +92,10 @@
class sky_pass;
class bloom_pass;
class final_pass;
class simple_render_pass;
// Animation
class animator;
// Systems
class behavior_system;
@ -109,6 +112,9 @@
class tool_system;
class control_system;
class ui_system;
template <class T>
class material_property;
//}
class application
@ -149,7 +155,9 @@ public:
const fsm::state& get_pause_state() const;
timeline* get_timeline();
animator* get_animator();
camera* get_camera();
camera* get_overworld_camera();
camera* get_underworld_camera();
orbit_cam* get_orbit_cam();
control_system* get_control_system();
@ -193,7 +201,7 @@ private:
// Updatable systems
timeline timeline;
animator animator;
animator* animator;
std::list<std::function<void(double, double)>> systems;
int shadow_map_resolution;
@ -210,16 +218,8 @@ private:
// Rendering
rasterizer* rasterizer;
material* fallback_material;
::clear_pass* clear_pass;
::sky_pass* sky_pass;
::material_pass* material_pass;
compositor default_compositor;
::clear_pass* shadow_map_clear_pass;
::shadow_map_pass* shadow_map_pass;
::bloom_pass* bloom_pass;
::final_pass* final_pass;
camera default_camera;
ambient_light sun_indirect;
directional_light sun_direct;
point_light subterrain_light;
@ -232,9 +232,29 @@ private:
vertex_buffer* billboard_vbo;
vertex_array* billboard_vao;
::renderer renderer;
scene* active_scene;
// Overworld
scene overworld_scene;
camera overworld_camera;
::clear_pass* clear_pass;
::sky_pass* sky_pass;
::material_pass* material_pass;
::clear_pass* shadow_map_clear_pass;
::shadow_map_pass* shadow_map_pass;
::bloom_pass* bloom_pass;
::final_pass* final_pass;
compositor overworld_compositor;
// Underworld
scene underworld_scene;
scene* active_scene;
camera underworld_camera;
::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;
// FSM
fsm::machine state_machine;
@ -354,12 +374,17 @@ inline timeline* application::get_timeline()
inline animator* application::get_animator()
{
return &animator;
return animator;
}
inline camera* application::get_overworld_camera()
{
return &overworld_camera;
}
inline camera* application::get_camera()
inline camera* application::get_underworld_camera()
{
return &default_camera;
return &underworld_camera;
}
inline orbit_cam* application::get_orbit_cam()

+ 42
- 1
src/debug/logger.cpp View File

@ -29,7 +29,8 @@ logger::logger():
error_prefix(std::string("Error: ")),
error_postfix(std::string()),
success_prefix(std::string("Success: ")),
success_postfix(std::string())
success_postfix(std::string()),
next_task_id(0)
{}
logger::~logger()
@ -120,3 +121,43 @@ void logger::pop_prefix()
prefix_stack.pop_back();
}
int logger::open_task(const std::string& text)
{
tasks[next_task_id] = text;
std::string indent;
for (std::size_t i = 0; i < tasks.size() - 1; ++i)
indent += " ";
log(indent + text + "...\n");
return next_task_id++;
}
bool logger::close_task(int id, int status)
{
auto it = tasks.find(id);
if (it == tasks.end())
return false;
std::string message = it->second + "... ";
std::string indent;
for (std::size_t i = 0; i < tasks.size() - 1; ++i)
indent += " ";
if (status == EXIT_SUCCESS)
{
message += "success\n";
log(indent + message);
}
else
{
message += "failed (" + std::to_string(status) + ")\n";
log(indent + message);
}
tasks.erase(it);
}

+ 20
- 0
src/debug/logger.hpp View File

@ -23,6 +23,7 @@
#include <list>
#include <ostream>
#include <string>
#include <unordered_map>
class logger
{
@ -56,6 +57,22 @@ public:
void push_prefix(const std::string& prefix);
void pop_prefix();
/**
* Opens a task and outputs it to the log.
*
* @return Task ID used to close the task later.
*/
int open_task(const std::string& text);
/**
* Closes a task and outputs its status to the log.
*
* @param id ID of the task to close.
* @param status Exit status of the task. A value of `0` or `EXIT_SUCCESS` indicates the task exited successfully. A non-zero exit status indicates the task failed.
* @return `true` if the task was closed, `false` if no task with the specified ID was found.
*/
bool close_task(int id, int status);
private:
std::ostream* os;
@ -68,6 +85,9 @@ private:
std::string success_prefix;
std::string success_postfix;
std::list<std::string> prefix_stack;
int next_task_id;
std::unordered_map<int, std::string> tasks;
};
#endif // ANTKEEPER_LOGGER_HPP

+ 2
- 2
src/nest.cpp View File

@ -74,7 +74,7 @@ float nest::get_shaft_angle(const shaft& shaft, float depth) const
float shaft_length = shaft.depth[1] - shaft.depth[0];
float depth_factor = (depth - shaft.depth[0]) / shaft_length;
float pitch = ease_linear(shaft.pitch[0], shaft.pitch[1], depth_factor);
return shaft.rotation + (depth / pitch) * shaft.chirality;
return shaft.rotation + (depth / pitch) * shaft.chirality * vmq::two_pi<float>;
}
float3 nest::get_shaft_position(const shaft& shaft, float depth) const
@ -86,7 +86,7 @@ float3 nest::get_shaft_position(const shaft& shaft, float depth) const
float radius = ease_out_expo(shaft.radius[0], shaft.radius[1], depth_factor);
float translation_x = ease_linear(shaft.translation[0][0], shaft.translation[1][0], depth_factor);
float translation_z = ease_linear(shaft.translation[0][1], shaft.translation[1][1], depth_factor);
float angle = shaft.rotation + (depth / pitch) * shaft.chirality;
float angle = shaft.rotation + (depth / pitch) * shaft.chirality * vmq::two_pi<float>;
float3 position;
position[0] = std::cos(angle) * radius + translation_x;

+ 6
- 0
src/renderer/renderer.cpp View File

@ -70,6 +70,12 @@ void renderer::render(float alpha, const scene& scene) const
// Process cameras in order
for (const camera* camera: sorted_cameras)
{
// Skip inactive cameras
if (!camera->is_active())
{
continue;
}
// Skip cameras with no compositors
const compositor* compositor = camera->get_compositor();
if (!compositor)

+ 6
- 0
src/renderer/renderer.hpp View File

@ -49,6 +49,12 @@ class renderer
public:
renderer();
/**
* Renders a scene.
*
* @param alpha Subframe interpolation factor.
* @parma scene Scene to render.
*/
void render(float alpha, const scene& scene) const;
/**

+ 115
- 0
src/renderer/simple-render-pass.cpp View File

@ -0,0 +1,115 @@
/*
* 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 "renderer/simple-render-pass.hpp"
#include "rasterizer/rasterizer.hpp"
#include "rasterizer/framebuffer.hpp"
#include "rasterizer/shader-program.hpp"
#include "rasterizer/shader-input.hpp"
#include "rasterizer/vertex-buffer.hpp"
#include "rasterizer/vertex-array.hpp"
#include "rasterizer/vertex-attribute-type.hpp"
#include "rasterizer/drawing-mode.hpp"
#include "rasterizer/texture-2d.hpp"
#include "rasterizer/texture-wrapping.hpp"
#include "rasterizer/texture-filter.hpp"
#include "renderer/vertex-attributes.hpp"
#include "renderer/render-context.hpp"
#include "renderer/material.hpp"
#include "renderer/material-property.hpp"
#include <vmq/vmq.hpp>
#include <glad/glad.h>
using namespace vmq;
simple_render_pass::simple_render_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, ::shader_program* shader_program):
render_pass(rasterizer, framebuffer),
shader_program(shader_program),
time_tween(nullptr)
{
// Create material
material = new ::material(shader_program);
// Add standard properties to material
time_property = material->add_property<float>("time");
resolution_property = material->add_property<float2>("resolution");
const float vertex_data[] =
{
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
std::size_t vertex_size = 3;
std::size_t vertex_stride = sizeof(float) * vertex_size;
std::size_t vertex_count = 6;
quad_vbo = new vertex_buffer(sizeof(float) * vertex_size * vertex_count, vertex_data);
quad_vao = new vertex_array();
quad_vao->bind_attribute(VERTEX_POSITION_LOCATION, *quad_vbo, 3, vertex_attribute_type::float_32, vertex_stride, 0);
}
simple_render_pass::~simple_render_pass()
{
delete material;
delete quad_vao;
delete quad_vbo;
}
void simple_render_pass::render(render_context* context) const
{
// Bind framebuffer
rasterizer->use_framebuffer(*framebuffer);
// Setup graphics context
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// Setup viewport
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
// Change shader program
rasterizer->use_program(*shader_program);
// Get interpolated time
float time = (time_tween) ? time_tween->interpolate(context->alpha) : 0.0f;
// Update material properties
time_property->set_value(time);
resolution_property->set_value({static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))});
// Upload material properties
material->upload();
// Draw quad
rasterizer->draw_arrays(*quad_vao, drawing_mode::triangles, 0, 6);
}
void simple_render_pass::set_time_tween(const tween<double>* time)
{
this->time_tween = time;
}

+ 74
- 0
src/renderer/simple-render-pass.hpp View File

@ -0,0 +1,74 @@
/*
* 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_SIMPLE_RENDER_PASS_HPP
#define ANTKEEPER_SIMPLE_RENDER_PASS_HPP
#include "renderer/render-pass.hpp"
#include "animation/tween.hpp"
#include <vmq/vmq.hpp>
using namespace vmq::types;
class shader_program;
class shader_input;
class vertex_buffer;
class vertex_array;
class material;
template <class T>
class material_property;
/**
* Simple render passes are associated with a single shader and a single material.
*/
class simple_render_pass: public render_pass
{
public:
simple_render_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, ::shader_program* shader_program);
virtual ~simple_render_pass();
virtual void render(render_context* context) const final;
void set_time_tween(const tween<double>* time);
const ::material* get_material() const;
::material* get_material();
private:
shader_program* shader_program;
material* material;
material_property<float>* time_property;
material_property<float2>* resolution_property;
const tween<double>* time_tween;
vertex_buffer* quad_vbo;
vertex_array* quad_vao;
};
inline const ::material* simple_render_pass::get_material() const
{
return material;
}
inline ::material* simple_render_pass::get_material()
{
return material;
}
#endif // ANTKEEPER_SIMPLE_RENDER_PASS_HPP

+ 7
- 1
src/resources/resource-manager.cpp View File

@ -19,7 +19,8 @@
#include "resources/resource-manager.hpp"
resource_manager::resource_manager()
resource_manager::resource_manager():
logger(nullptr)
{}
resource_manager::~resource_manager()
@ -55,3 +56,8 @@ void resource_manager::include(const std::string& path)
paths.push_back(path);
}
void resource_manager::set_logger(::logger* logger)
{
this->logger = logger;
}

+ 25
- 0
src/resources/resource-manager.hpp View File

@ -22,6 +22,7 @@
#include "resource-handle.hpp"
#include "resource-loader.hpp"
#include "debug/logger.hpp"
#include <fstream>
#include <list>
#include <map>
@ -80,11 +81,14 @@ public:
void save(const T* resource, const std::string& path);
entt::registry& get_archetype_registry();
void set_logger(::logger* logger);
private:
std::map<std::string, resource_handle_base*> resource_cache;
std::list<std::string> paths;
entt::registry archetype_registry;
::logger* logger;
};
template <typename T>
@ -103,6 +107,12 @@ T* resource_manager::load(const std::string& path)
// Return resource data
return resource->data;
}
int task_id;
if (logger)
{
task_id = logger->open_task("Loading resource \"" + path + "\"");
}
// Resource not found, load resource data
T* data = nullptr;
@ -138,11 +148,21 @@ T* resource_manager::load(const std::string& path)
if (!opened)
{
if (logger)
{
logger->close_task(task_id, EXIT_FAILURE);
}
throw std::runtime_error("resource_manager::load<T>(): Unable to open file \"" + path + "\"");
}
}
catch (const std::exception& e)
{
if (logger)
{
logger->close_task(task_id, EXIT_FAILURE);
}
std::string error = std::string("resource_manager::load<T>(): Failed to load resource \"") + path + std::string("\": \"") + e.what() + std::string("\"");
throw std::runtime_error(error.c_str());
}
@ -154,6 +174,11 @@ T* resource_manager::load(const std::string& path)
// Add resource to the cache
resource_cache[path] = resource;
if (logger)
{
logger->close_task(task_id, EXIT_SUCCESS);
}
return resource->data;
}

+ 4
- 4
src/state/loading-state.cpp View File

@ -24,9 +24,9 @@
void enter_loading_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Entering loading state...\n");
int task_id = logger->open_task("Entering loading state");
logger->success("Entering loading state... success\n");
logger->close_task(task_id, EXIT_SUCCESS);
app->get_state_machine()->change_state(app->get_title_state());
}
@ -34,8 +34,8 @@ void enter_loading_state(application* app)
void exit_loading_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Exiting loading state...\n");
int task_id = logger->open_task("Exiting loading state");
logger->success("Exiting loading state... success\n");
logger->close_task(task_id, EXIT_SUCCESS);
}

+ 7
- 5
src/state/play-state.cpp View File

@ -44,7 +44,7 @@ using namespace vmq::operators;
void enter_play_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Entering play state...\n");
int enter_state_task = logger->open_task("Entering play state");
resource_manager* resource_manager = app->get_resource_manager();
@ -138,8 +138,8 @@ void enter_play_state(application* app)
ecs_registry.get<ecs::transform_component>(grass_entity_2).transform.rotation = vmq::angle_axis(vmq::radians(120.0f), float3{0, 1, 0});
*/
// Setup camera
camera* camera = app->get_camera();
// Setup overworld camera
camera* camera = app->get_overworld_camera();
orbit_cam* orbit_cam = app->get_orbit_cam();
orbit_cam->attach(camera);
orbit_cam->set_target_focal_point({0, 0, 0});
@ -227,14 +227,16 @@ void enter_play_state(application* app)
control_system->set_nest(nest);
orbit_cam->update(0.0f);
logger->success("Entering play state... success\n");
logger->close_task(enter_state_task, EXIT_SUCCESS);
}
void exit_play_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Exiting play state...\n");
int exit_state_task = logger->open_task("Exiting play state");
logger->success("Exiting play state... success\n");
logger->close_task(exit_state_task, EXIT_SUCCESS);
}

+ 30
- 10
src/state/splash-state.cpp View File

@ -19,32 +19,52 @@
#include "application-states.hpp"
#include "application.hpp"
#include <functional>
#include <iostream>
void enter_splash_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Entering splash state...\n");
logger* logger = app->get_logger();
int task_id = logger->open_task("Entering splash state");
auto fade_in = [logger]()
{
logger->log("cue logo fade-in\n");
};
auto fade_out = [logger]()
{
logger->log("cue logo fade-out\n");
};
auto change_state = [app]()
{
app->get_state_machine()->change_state(app->get_title_state());
};
// Get timeline
timeline* timeline = app->get_timeline();
float t = timeline->get_position();
// Create splash sequence
float t = timeline->get_position();
sequence splash_sequence =
{
{t + 0.0f, [logger](){ logger->log("cue logo fade-in\n"); }},
{t + 3.0f, [logger](){ logger->log("cue logo fade-out\n"); }},
{t + 8.0f, [app](){ app->get_state_machine()->change_state(app->get_play_state()); }}
{t + 0.0f, fade_in},
{t + 3.0f, fade_out},
{t + 8.0f, change_state}
};
// Add splash sequence to timeline
timeline->add_sequence(splash_sequence);
logger->success("Entering splash state... success\n");
logger->close_task(task_id, EXIT_SUCCESS);
}
void exit_splash_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Exiting splash state...\n");
logger->success("Exiting splash state... success\n");
int task_id = logger->open_task("Exiting splash state");
logger->close_task(task_id, EXIT_SUCCESS);
}

+ 10
- 9
src/state/title-state.cpp View File

@ -19,17 +19,18 @@
#include "application-states.hpp"
#include "application.hpp"
#include <iostream>
void enter_title_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Entering title state...\n");
int task_id = logger->open_task("Entering title state");
// Get timeline
timeline* timeline = app->get_timeline();
// Create title sequence
float t = timeline->get_position();
sequence startup_sequence =
sequence title_sequence =
{
{t + 0.0f, [logger](){ logger->log("cue sound fade-in\n"); }},
{t + 3.0f, [logger](){ logger->log("cue scene fade-in from black\n"); }},
@ -37,17 +38,17 @@ void enter_title_state(application* app)
{t + 10.0f, [logger](){ logger->log("cue menu fade-in\n"); }}
};
timeline->add_sequence(startup_sequence);
// Add title sequence to timeline
timeline->add_sequence(title_sequence);
logger->success("Entering title state... success\n");
logger->close_task(task_id, EXIT_SUCCESS);
}
void exit_title_state(application* app)
{
logger* logger = app->get_logger();
logger->log("Exiting title state...\n");
int task_id = logger->open_task("Exiting title state");
logger->success("Exiting title state... success\n");
logger->close_task(task_id, EXIT_SUCCESS);
}

+ 10
- 0
src/systems/ui-system.cpp View File

@ -158,3 +158,13 @@ void ui_system::close_tool_menu()
scene.remove_object(&tool_selector_bg);
scene.remove_object(&tool_selector_ant);
}
void ui_system::open_elevator_menu()
{
}
void ui_system::close_elevator_menu()
{
}

+ 5
- 0
src/systems/ui-system.hpp View File

@ -58,6 +58,9 @@ private:
void open_tool_menu();
void close_tool_menu();
void open_elevator_menu();
void close_elevator_menu();
::resource_manager* resource_manager;
::scene scene;
@ -69,6 +72,8 @@ private:
material modal_bg_material;
billboard modal_bg;
billboard underground_bg;
model_instance energy_symbol;
float2 mouse_position;

Loading…
Cancel
Save