mirror of https://github.com/auygun/kaliber.git
Compare commits
6 Commits
67632ff144
...
709029f22c
Author | SHA1 | Date |
---|---|---|
Attila Uygun | 709029f22c | |
Attila Uygun | 8e6589ec67 | |
Attila Uygun | 69a05c00e9 | |
Attila Uygun | d7e444fa81 | |
Attila Uygun | 8a87597911 | |
Attila Uygun | 22d80d6152 |
|
@ -11,11 +11,12 @@ namespace {
|
||||||
void PostTaskAndReplyRelay(Location from,
|
void PostTaskAndReplyRelay(Location from,
|
||||||
Closure task_cb,
|
Closure task_cb,
|
||||||
Closure reply_cb,
|
Closure reply_cb,
|
||||||
std::shared_ptr<TaskRunner> destination) {
|
std::shared_ptr<TaskRunner> destination,
|
||||||
|
bool front) {
|
||||||
task_cb();
|
task_cb();
|
||||||
|
|
||||||
if (reply_cb)
|
if (reply_cb)
|
||||||
destination->PostTask(from, std::move(reply_cb));
|
destination->PostTask(from, std::move(reply_cb), front);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -36,22 +37,28 @@ std::shared_ptr<TaskRunner> TaskRunner::GetThreadLocalTaskRunner() {
|
||||||
return thread_local_task_runner;
|
return thread_local_task_runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskRunner::PostTask(Location from, Closure task) {
|
void TaskRunner::PostTask(Location from, Closure task, bool front) {
|
||||||
DCHECK(task) << LOCATION(from);
|
DCHECK(task) << LOCATION(from);
|
||||||
|
|
||||||
task_count_.fetch_add(1, std::memory_order_relaxed);
|
task_count_.fetch_add(1, std::memory_order_relaxed);
|
||||||
std::lock_guard<std::mutex> scoped_lock(lock_);
|
std::lock_guard<std::mutex> scoped_lock(lock_);
|
||||||
|
if (front)
|
||||||
|
queue_.emplace_front(from, std::move(task));
|
||||||
|
else
|
||||||
queue_.emplace_back(from, std::move(task));
|
queue_.emplace_back(from, std::move(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskRunner::PostTaskAndReply(Location from, Closure task, Closure reply) {
|
void TaskRunner::PostTaskAndReply(Location from,
|
||||||
|
Closure task,
|
||||||
|
Closure reply,
|
||||||
|
bool front) {
|
||||||
DCHECK(task) << LOCATION(from);
|
DCHECK(task) << LOCATION(from);
|
||||||
DCHECK(reply) << LOCATION(from);
|
DCHECK(reply) << LOCATION(from);
|
||||||
DCHECK(thread_local_task_runner) << LOCATION(from);
|
DCHECK(thread_local_task_runner) << LOCATION(from);
|
||||||
|
|
||||||
auto relay = std::bind(PostTaskAndReplyRelay, from, std::move(task),
|
auto relay = std::bind(PostTaskAndReplyRelay, from, std::move(task),
|
||||||
std::move(reply), thread_local_task_runner);
|
std::move(reply), thread_local_task_runner, front);
|
||||||
PostTask(from, std::move(relay));
|
PostTask(from, std::move(relay), front);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskRunner::CancelTasks() {
|
void TaskRunner::CancelTasks() {
|
||||||
|
|
|
@ -18,16 +18,15 @@ namespace internal {
|
||||||
// one that returns via an output parameter.
|
// one that returns via an output parameter.
|
||||||
template <typename ReturnType>
|
template <typename ReturnType>
|
||||||
void ReturnAsParamAdapter(std::function<ReturnType()> func,
|
void ReturnAsParamAdapter(std::function<ReturnType()> func,
|
||||||
ReturnType* result) {
|
std::shared_ptr<ReturnType> result) {
|
||||||
*result = func();
|
*result = func();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adapts a ReturnType* result to a callblack that expects a ReturnType.
|
// Adapts a ReturnType* result to a callblack that expects a ReturnType.
|
||||||
template <typename ReturnType>
|
template <typename ReturnType>
|
||||||
void ReplyAdapter(std::function<void(ReturnType)> callback,
|
void ReplyAdapter(std::function<void(ReturnType)> callback,
|
||||||
ReturnType* result) {
|
std::shared_ptr<ReturnType> result) {
|
||||||
callback(std::move(*result));
|
callback(std::move(*result));
|
||||||
delete result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -45,21 +44,32 @@ class TaskRunner {
|
||||||
static void CreateThreadLocalTaskRunner();
|
static void CreateThreadLocalTaskRunner();
|
||||||
static std::shared_ptr<TaskRunner> GetThreadLocalTaskRunner();
|
static std::shared_ptr<TaskRunner> GetThreadLocalTaskRunner();
|
||||||
|
|
||||||
void PostTask(Location from, Closure task);
|
void PostTask(Location from, Closure task, bool front = false);
|
||||||
|
|
||||||
void PostTaskAndReply(Location from, Closure task, Closure reply);
|
void PostTaskAndReply(Location from,
|
||||||
|
Closure task,
|
||||||
|
Closure reply,
|
||||||
|
bool front = false);
|
||||||
|
|
||||||
template <typename ReturnType>
|
template <typename ReturnType>
|
||||||
void PostTaskAndReplyWithResult(Location from,
|
void PostTaskAndReplyWithResult(Location from,
|
||||||
std::function<ReturnType()> task,
|
std::function<ReturnType()> task,
|
||||||
std::function<void(ReturnType)> reply) {
|
std::function<void(ReturnType)> reply,
|
||||||
auto* result = new ReturnType;
|
bool front = false) {
|
||||||
|
auto result = std::make_shared<ReturnType>();
|
||||||
return PostTaskAndReply(
|
return PostTaskAndReply(
|
||||||
from,
|
from,
|
||||||
std::bind(internal::ReturnAsParamAdapter<ReturnType>, std::move(task),
|
std::bind(internal::ReturnAsParamAdapter<ReturnType>, std::move(task),
|
||||||
result),
|
result),
|
||||||
std::bind(internal::ReplyAdapter<ReturnType>, std::move(reply),
|
std::bind(internal::ReplyAdapter<ReturnType>, std::move(reply), result),
|
||||||
result));
|
front);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Posts a task to delete the given object.
|
||||||
|
template <class T>
|
||||||
|
void Delete(Location from, std::unique_ptr<T> object) {
|
||||||
|
std::shared_ptr<T> owned = std::move(object);
|
||||||
|
PostTask(HERE, [owned]() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CancelTasks();
|
void CancelTasks();
|
||||||
|
|
|
@ -40,17 +40,20 @@ void ThreadPool::Shutdown() {
|
||||||
threads_.clear();
|
threads_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::PostTask(Location from, Closure task) {
|
void ThreadPool::PostTask(Location from, Closure task, bool front) {
|
||||||
DCHECK((!threads_.empty()));
|
DCHECK((!threads_.empty()));
|
||||||
|
|
||||||
task_runner_.PostTask(from, std::move(task));
|
task_runner_.PostTask(from, std::move(task), front);
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadPool::PostTaskAndReply(Location from, Closure task, Closure reply) {
|
void ThreadPool::PostTaskAndReply(Location from,
|
||||||
|
Closure task,
|
||||||
|
Closure reply,
|
||||||
|
bool front) {
|
||||||
DCHECK((!threads_.empty()));
|
DCHECK((!threads_.empty()));
|
||||||
|
|
||||||
task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply));
|
task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply), front);
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,16 +24,20 @@ class ThreadPool {
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void PostTask(Location from, Closure task);
|
void PostTask(Location from, Closure task, bool front = false);
|
||||||
|
|
||||||
void PostTaskAndReply(Location from, Closure task, Closure reply);
|
void PostTaskAndReply(Location from,
|
||||||
|
Closure task,
|
||||||
|
Closure reply,
|
||||||
|
bool front = false);
|
||||||
|
|
||||||
template <typename ReturnType>
|
template <typename ReturnType>
|
||||||
void PostTaskAndReplyWithResult(Location from,
|
void PostTaskAndReplyWithResult(Location from,
|
||||||
std::function<ReturnType()> task,
|
std::function<ReturnType()> task,
|
||||||
std::function<void(ReturnType)> reply) {
|
std::function<void(ReturnType)> reply,
|
||||||
|
bool front = false) {
|
||||||
task_runner_.PostTaskAndReplyWithResult(from, std::move(task),
|
task_runner_.PostTaskAndReplyWithResult(from, std::move(task),
|
||||||
std::move(reply));
|
std::move(reply), front);
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "engine/game_factory.h"
|
#include "engine/game_factory.h"
|
||||||
#include "engine/input_event.h"
|
#include "engine/input_event.h"
|
||||||
#include "engine/sound.h"
|
|
||||||
|
|
||||||
DECLARE_GAME_BEGIN
|
DECLARE_GAME_BEGIN
|
||||||
DECLARE_GAME(Demo)
|
DECLARE_GAME(Demo)
|
||||||
|
@ -47,16 +46,38 @@ Demo::~Demo() {
|
||||||
saved_data_.Save();
|
saved_data_.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Demo::Initialize() {
|
bool Demo::PreInitialize() {
|
||||||
saved_data_.Load(kSaveFileName);
|
|
||||||
|
|
||||||
Engine::Get().LoadCustomShader("sky_without_nebula",
|
|
||||||
"sky_without_nebula.glsl");
|
|
||||||
Engine::Get().LoadCustomShader("sky", "sky.glsl");
|
|
||||||
|
|
||||||
if (!font_.Load("PixelCaps!.ttf"))
|
if (!font_.Load("PixelCaps!.ttf"))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Engine::Get().SetShaderSource("sky_without_nebula",
|
||||||
|
"sky_without_nebula.glsl");
|
||||||
|
Engine::Get().SetShaderSource("sky", "sky.glsl");
|
||||||
|
|
||||||
|
Engine::Get().AsyncLoadSound("music", "Game_2_Main.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("boss_music", "Game_2_Boss.mp3");
|
||||||
|
|
||||||
|
if (!enemy_.PreInitialize()) {
|
||||||
|
LOG << "Failed to create the enemy.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player_.PreInitialize()) {
|
||||||
|
LOG << "Failed to create the enemy.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menu_.PreInitialize()) {
|
||||||
|
LOG << "Failed to create the menu.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Demo::Initialize() {
|
||||||
|
saved_data_.Load(kSaveFileName);
|
||||||
|
|
||||||
if (!sky_.Create(false)) {
|
if (!sky_.Create(false)) {
|
||||||
LOG << "Could not create the sky.";
|
LOG << "Could not create the sky.";
|
||||||
return false;
|
return false;
|
||||||
|
@ -87,18 +108,10 @@ bool Demo::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sound = std::make_unique<Sound>();
|
music_.SetSound("music");
|
||||||
if (!sound->Load("Game_2_Main.mp3", true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto boss_sound = std::make_unique<Sound>();
|
|
||||||
if (!boss_sound->Load("Game_2_Boss.mp3", true))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
music_.SetSound(std::move(sound));
|
|
||||||
music_.SetMaxAplitude(0.5f);
|
music_.SetMaxAplitude(0.5f);
|
||||||
|
|
||||||
boss_music_.SetSound(std::move(boss_sound));
|
boss_music_.SetSound("boss_music");
|
||||||
boss_music_.SetMaxAplitude(0.5f);
|
boss_music_.SetMaxAplitude(0.5f);
|
||||||
|
|
||||||
if (!saved_data_.root().get("audio", Json::Value(true)).asBool())
|
if (!saved_data_.root().get("audio", Json::Value(true)).asBool())
|
||||||
|
@ -172,6 +185,7 @@ void Demo::ContextLost() {
|
||||||
num_benchmark_samples_ = 0;
|
num_benchmark_samples_ = 0;
|
||||||
avarage_fps_ = 0;
|
avarage_fps_ = 0;
|
||||||
}
|
}
|
||||||
|
menu_.SetRendererType();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Demo::LostFocus() {}
|
void Demo::LostFocus() {}
|
||||||
|
|
|
@ -23,14 +23,12 @@ class Demo final : public eng::Game {
|
||||||
Demo();
|
Demo();
|
||||||
~Demo() final;
|
~Demo() final;
|
||||||
|
|
||||||
|
// Game interface
|
||||||
|
bool PreInitialize() final;
|
||||||
bool Initialize() final;
|
bool Initialize() final;
|
||||||
|
|
||||||
void Update(float delta_time) final;
|
void Update(float delta_time) final;
|
||||||
|
|
||||||
void ContextLost() final;
|
void ContextLost() final;
|
||||||
|
|
||||||
void LostFocus() final;
|
void LostFocus() final;
|
||||||
|
|
||||||
void GainedFocus(bool from_interstitial_ad) final;
|
void GainedFocus(bool from_interstitial_ad) final;
|
||||||
|
|
||||||
void AddScore(size_t score);
|
void AddScore(size_t score);
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "engine/font.h"
|
#include "engine/font.h"
|
||||||
#include "engine/image.h"
|
#include "engine/image.h"
|
||||||
#include "engine/renderer/geometry.h"
|
#include "engine/renderer/geometry.h"
|
||||||
#include "engine/sound.h"
|
|
||||||
|
|
||||||
#include "demo/demo.h"
|
#include "demo/demo.h"
|
||||||
|
|
||||||
|
@ -78,46 +77,44 @@ Enemy::Enemy() = default;
|
||||||
|
|
||||||
Enemy::~Enemy() = default;
|
Enemy::~Enemy() = default;
|
||||||
|
|
||||||
|
bool Enemy::PreInitialize() {
|
||||||
|
Engine::Get().SetImageSource("skull_tex", "enemy_anims_01_frames_ok.png",
|
||||||
|
true);
|
||||||
|
Engine::Get().SetImageSource("bug_tex", "enemy_anims_02_frames_ok.png", true);
|
||||||
|
Engine::Get().SetImageSource("boss_tex1", "Boss_ok.png", true);
|
||||||
|
Engine::Get().SetImageSource("boss_tex2", "Boss_ok_lvl2.png", true);
|
||||||
|
Engine::Get().SetImageSource("boss_tex3", "Boss_ok_lvl3.png", true);
|
||||||
|
Engine::Get().SetImageSource("target_tex", "enemy_target_single_ok.png",
|
||||||
|
true);
|
||||||
|
Engine::Get().SetImageSource("blast_tex", "enemy_anims_blast_ok.png", true);
|
||||||
|
Engine::Get().SetImageSource("shield_tex", "woom_enemy_shield.png", true);
|
||||||
|
Engine::Get().SetImageSource("crate_tex", "nuke_pack_OK.png", true);
|
||||||
|
|
||||||
|
for (int i = 0; i < kEnemyType_Max; ++i)
|
||||||
|
Engine::Get().SetImageSource(
|
||||||
|
"score_tex"s + std::to_string(i),
|
||||||
|
std::bind(&Enemy::GetScoreImage, this, (EnemyType)i), true);
|
||||||
|
|
||||||
|
Engine::Get().SetShaderSource("chromatic_aberration",
|
||||||
|
"chromatic_aberration.glsl");
|
||||||
|
|
||||||
|
Engine::Get().AsyncLoadSound("boss_intro", "boss_intro.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("boss_explosion", "boss_explosion.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("explosion", "explosion.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("stealth", "stealth.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("shield", "shield.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("hit", "hit.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("powerup-spawn", "powerup-spawn.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("powerup-pick", "powerup-pick.mp3");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Enemy::Initialize() {
|
bool Enemy::Initialize() {
|
||||||
boss_intro_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!boss_intro_sound_->Load("boss_intro.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
boss_explosion_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!boss_explosion_sound_->Load("boss_explosion.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
explosion_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!explosion_sound_->Load("explosion.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
stealth_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!stealth_sound_->Load("stealth.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
shield_on_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!shield_on_sound_->Load("shield.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
hit_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!hit_sound_->Load("hit.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
power_up_spawn_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!power_up_spawn_sound_->Load("powerup-spawn.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
power_up_pick_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!power_up_pick_sound_->Load("powerup-pick.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!CreateRenderResources())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
boss_.SetZOrder(10);
|
boss_.SetZOrder(10);
|
||||||
boss_animator_.Attach(&boss_);
|
boss_animator_.Attach(&boss_);
|
||||||
|
|
||||||
boss_intro_.SetSound(boss_intro_sound_);
|
boss_intro_.SetSound("boss_intro");
|
||||||
boss_intro_.SetVariate(false);
|
boss_intro_.SetVariate(false);
|
||||||
boss_intro_.SetSimulateStereo(false);
|
boss_intro_.SetSimulateStereo(false);
|
||||||
|
|
||||||
|
@ -729,29 +726,29 @@ void Enemy::SpawnUnit(EnemyType enemy_type,
|
||||||
e.movement_animator.Play(Animator::kMovement, false);
|
e.movement_animator.Play(Animator::kMovement, false);
|
||||||
|
|
||||||
if (e.enemy_type == kEnemyType_PowerUp) {
|
if (e.enemy_type == kEnemyType_PowerUp) {
|
||||||
e.explosion.SetSound(power_up_pick_sound_);
|
e.explosion.SetSound("powerup-pick");
|
||||||
|
|
||||||
e.spawn.SetSound(power_up_spawn_sound_);
|
e.spawn.SetSound("powerup-spawn");
|
||||||
e.spawn.SetMaxAplitude(2.0f);
|
e.spawn.SetMaxAplitude(2.0f);
|
||||||
e.spawn.Play(false);
|
e.spawn.Play(false);
|
||||||
} else {
|
} else {
|
||||||
e.explosion.SetSound(explosion_sound_);
|
e.explosion.SetSound("explosion");
|
||||||
e.explosion.SetVariate(true);
|
e.explosion.SetVariate(true);
|
||||||
e.explosion.SetSimulateStereo(true);
|
e.explosion.SetSimulateStereo(true);
|
||||||
e.explosion.SetMaxAplitude(0.9f);
|
e.explosion.SetMaxAplitude(0.9f);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.stealth.SetSound(stealth_sound_);
|
e.stealth.SetSound("stealth");
|
||||||
e.stealth.SetVariate(false);
|
e.stealth.SetVariate(false);
|
||||||
e.stealth.SetSimulateStereo(false);
|
e.stealth.SetSimulateStereo(false);
|
||||||
e.stealth.SetMaxAplitude(0.7f);
|
e.stealth.SetMaxAplitude(0.7f);
|
||||||
|
|
||||||
e.shield_on.SetSound(shield_on_sound_);
|
e.shield_on.SetSound("shield");
|
||||||
e.shield_on.SetVariate(false);
|
e.shield_on.SetVariate(false);
|
||||||
e.shield_on.SetSimulateStereo(false);
|
e.shield_on.SetSimulateStereo(false);
|
||||||
e.shield_on.SetMaxAplitude(0.5f);
|
e.shield_on.SetMaxAplitude(0.5f);
|
||||||
|
|
||||||
e.hit.SetSound(hit_sound_);
|
e.hit.SetSound("hit");
|
||||||
e.hit.SetVariate(true);
|
e.hit.SetVariate(true);
|
||||||
e.hit.SetSimulateStereo(false);
|
e.hit.SetSimulateStereo(false);
|
||||||
e.hit.SetMaxAplitude(0.5f);
|
e.hit.SetMaxAplitude(0.5f);
|
||||||
|
@ -825,11 +822,11 @@ void Enemy::SpawnBoss() {
|
||||||
Animator::kMovement, [&]() -> void { e.marked_for_removal = true; });
|
Animator::kMovement, [&]() -> void { e.marked_for_removal = true; });
|
||||||
e.score_animator.Attach(&e.score);
|
e.score_animator.Attach(&e.score);
|
||||||
|
|
||||||
e.explosion.SetSound(boss_explosion_sound_);
|
e.explosion.SetSound("boss_explosion");
|
||||||
e.explosion.SetVariate(false);
|
e.explosion.SetVariate(false);
|
||||||
e.explosion.SetSimulateStereo(false);
|
e.explosion.SetSimulateStereo(false);
|
||||||
|
|
||||||
e.hit.SetSound(hit_sound_);
|
e.hit.SetSound("hit");
|
||||||
e.hit.SetVariate(true);
|
e.hit.SetVariate(true);
|
||||||
e.hit.SetSimulateStereo(false);
|
e.hit.SetSimulateStereo(false);
|
||||||
e.hit.SetMaxAplitude(0.5f);
|
e.hit.SetMaxAplitude(0.5f);
|
||||||
|
@ -1185,30 +1182,6 @@ std::unique_ptr<Image> Enemy::GetScoreImage(EnemyType enemy_type) {
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Enemy::CreateRenderResources() {
|
|
||||||
Engine::Get().SetImageSource("skull_tex", "enemy_anims_01_frames_ok.png",
|
|
||||||
true);
|
|
||||||
Engine::Get().SetImageSource("bug_tex", "enemy_anims_02_frames_ok.png", true);
|
|
||||||
Engine::Get().SetImageSource("boss_tex1", "Boss_ok.png", true);
|
|
||||||
Engine::Get().SetImageSource("boss_tex2", "Boss_ok_lvl2.png", true);
|
|
||||||
Engine::Get().SetImageSource("boss_tex3", "Boss_ok_lvl3.png", true);
|
|
||||||
Engine::Get().SetImageSource("target_tex", "enemy_target_single_ok.png",
|
|
||||||
true);
|
|
||||||
Engine::Get().SetImageSource("blast_tex", "enemy_anims_blast_ok.png", true);
|
|
||||||
Engine::Get().SetImageSource("shield_tex", "woom_enemy_shield.png", true);
|
|
||||||
Engine::Get().SetImageSource("crate_tex", "nuke_pack_OK.png", true);
|
|
||||||
|
|
||||||
for (int i = 0; i < kEnemyType_Max; ++i)
|
|
||||||
Engine::Get().SetImageSource(
|
|
||||||
"score_tex"s + std::to_string(i),
|
|
||||||
std::bind(&Enemy::GetScoreImage, this, (EnemyType)i), true);
|
|
||||||
|
|
||||||
Engine::Get().LoadCustomShader("chromatic_aberration",
|
|
||||||
"chromatic_aberration.glsl");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Enemy::TranslateEnemyUnit(EnemyUnit& e, const Vector2f& delta) {
|
void Enemy::TranslateEnemyUnit(EnemyUnit& e, const Vector2f& delta) {
|
||||||
e.sprite.Translate(delta);
|
e.sprite.Translate(delta);
|
||||||
e.target.Translate(delta);
|
e.target.Translate(delta);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
class Image;
|
class Image;
|
||||||
class Sound;
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
||||||
class Enemy {
|
class Enemy {
|
||||||
|
@ -23,6 +22,7 @@ class Enemy {
|
||||||
Enemy();
|
Enemy();
|
||||||
~Enemy();
|
~Enemy();
|
||||||
|
|
||||||
|
bool PreInitialize();
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
void Update(float delta_time);
|
void Update(float delta_time);
|
||||||
|
@ -109,15 +109,6 @@ class Enemy {
|
||||||
eng::Animator boss_animator_;
|
eng::Animator boss_animator_;
|
||||||
eng::SoundPlayer boss_intro_;
|
eng::SoundPlayer boss_intro_;
|
||||||
|
|
||||||
std::shared_ptr<eng::Sound> boss_intro_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> boss_explosion_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> explosion_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> stealth_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> shield_on_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> hit_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> power_up_spawn_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> power_up_pick_sound_;
|
|
||||||
|
|
||||||
std::list<EnemyUnit> enemies_;
|
std::list<EnemyUnit> enemies_;
|
||||||
|
|
||||||
int num_enemies_killed_in_current_wave_ = 0;
|
int num_enemies_killed_in_current_wave_ = 0;
|
||||||
|
@ -164,8 +155,6 @@ class Enemy {
|
||||||
|
|
||||||
std::unique_ptr<eng::Image> GetScoreImage(EnemyType enemy_type);
|
std::unique_ptr<eng::Image> GetScoreImage(EnemyType enemy_type);
|
||||||
|
|
||||||
bool CreateRenderResources();
|
|
||||||
|
|
||||||
void TranslateEnemyUnit(EnemyUnit& e, const base::Vector2f& delta);
|
void TranslateEnemyUnit(EnemyUnit& e, const base::Vector2f& delta);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
111
src/demo/menu.cc
111
src/demo/menu.cc
|
@ -53,7 +53,7 @@ Menu::Menu() = default;
|
||||||
|
|
||||||
Menu::~Menu() = default;
|
Menu::~Menu() = default;
|
||||||
|
|
||||||
bool Menu::Initialize() {
|
bool Menu::PreInitialize() {
|
||||||
click_sound_ = std::make_shared<Sound>();
|
click_sound_ = std::make_shared<Sound>();
|
||||||
if (!click_sound_->Load("menu_click.mp3", false))
|
if (!click_sound_->Load("menu_click.mp3", false))
|
||||||
return false;
|
return false;
|
||||||
|
@ -70,8 +70,59 @@ bool Menu::Initialize() {
|
||||||
max_text_width_ = width;
|
max_text_width_ = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateRenderResources())
|
Engine::Get().SetImageSource("menu_tex",
|
||||||
return false;
|
std::bind(&Menu::CreateMenuImage, this), true);
|
||||||
|
Engine::Get().SetImageSource("logo_tex0", "woom_logo_start_frames_01.png",
|
||||||
|
true);
|
||||||
|
Engine::Get().SetImageSource("logo_tex1", "woom_logo_start_frames_02-03.png",
|
||||||
|
true);
|
||||||
|
Engine::Get().SetImageSource("buttons_tex", "menu_icons.png", true);
|
||||||
|
Engine::Get().SetImageSource("renderer_logo", "renderer_logo.png", true);
|
||||||
|
|
||||||
|
Engine::Get().SetImageSource(
|
||||||
|
"version_tex",
|
||||||
|
[]() -> std::unique_ptr<Image> {
|
||||||
|
const Font* font = Engine::Get().GetSystemFont();
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
font->CalculateBoundingBox(kVersionStr, w, h);
|
||||||
|
|
||||||
|
auto image = std::make_unique<Image>();
|
||||||
|
image->Create(w, font->GetLineHeight());
|
||||||
|
image->Clear({1, 1, 1, 0});
|
||||||
|
|
||||||
|
font->Print(0, 0, kVersionStr, image->GetBuffer(), image->GetWidth());
|
||||||
|
|
||||||
|
image->Compress();
|
||||||
|
return image;
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
|
||||||
|
Engine::Get().SetImageSource("high_score_tex",
|
||||||
|
std::bind(&Menu::CreateHighScoreImage, this));
|
||||||
|
Engine::Get().SetImageSource("wave_up_tex", []() -> std::unique_ptr<Image> {
|
||||||
|
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
||||||
|
|
||||||
|
constexpr char btn_text[] = "[ ]";
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
font.CalculateBoundingBox(btn_text, w, h);
|
||||||
|
|
||||||
|
auto image = std::make_unique<Image>();
|
||||||
|
image->Create(w, h);
|
||||||
|
image->Clear({1, 1, 1, 0});
|
||||||
|
|
||||||
|
font.Print(0, 0, btn_text, image->GetBuffer(), image->GetWidth());
|
||||||
|
|
||||||
|
image->Compress();
|
||||||
|
return image;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Menu::Initialize() {
|
||||||
|
Demo* game = static_cast<Demo*>(Engine::Get().GetGame());
|
||||||
|
|
||||||
for (int i = 0; i < kOption_Max; ++i) {
|
for (int i = 0; i < kOption_Max; ++i) {
|
||||||
items_[i].text.Create("menu_tex", {1, 4});
|
items_[i].text.Create("menu_tex", {1, 4});
|
||||||
|
@ -199,8 +250,6 @@ bool Menu::Initialize() {
|
||||||
Engine::Get().CreateRenderer(renderer_type_.enabled()
|
Engine::Get().CreateRenderer(renderer_type_.enabled()
|
||||||
? RendererType::kVulkan
|
? RendererType::kVulkan
|
||||||
: RendererType::kOpenGL);
|
: RendererType::kOpenGL);
|
||||||
renderer_type_.SetEnabled(
|
|
||||||
(Engine::Get().GetRendererType() == RendererType::kVulkan));
|
|
||||||
},
|
},
|
||||||
true, Engine::Get().GetRendererType() == RendererType::kVulkan,
|
true, Engine::Get().GetRendererType() == RendererType::kVulkan,
|
||||||
kColorFadeOut, {Vector4f{1, 1, 1, 1}, Vector4f{1, 1, 1, 1}});
|
kColorFadeOut, {Vector4f{1, 1, 1, 1}, Vector4f{1, 1, 1, 1}});
|
||||||
|
@ -320,6 +369,11 @@ void Menu::SetOptionEnabled(Option o, bool enable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Menu::SetRendererType() {
|
||||||
|
renderer_type_.SetEnabled(
|
||||||
|
(Engine::Get().GetRendererType() == RendererType::kVulkan));
|
||||||
|
}
|
||||||
|
|
||||||
void Menu::Show() {
|
void Menu::Show() {
|
||||||
logo_[1].SetColor(kColorNormal);
|
logo_[1].SetColor(kColorNormal);
|
||||||
logo_animator_[0].SetVisible(true);
|
logo_animator_[0].SetVisible(true);
|
||||||
|
@ -440,53 +494,6 @@ void Menu::Hide(Closure cb) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Menu::CreateRenderResources() {
|
|
||||||
Engine::Get().SetImageSource("menu_tex",
|
|
||||||
std::bind(&Menu::CreateMenuImage, this));
|
|
||||||
Engine::Get().SetImageSource("logo_tex0", "woom_logo_start_frames_01.png");
|
|
||||||
Engine::Get().SetImageSource("logo_tex1", "woom_logo_start_frames_02-03.png");
|
|
||||||
Engine::Get().SetImageSource("buttons_tex", "menu_icons.png");
|
|
||||||
Engine::Get().SetImageSource("high_score_tex",
|
|
||||||
std::bind(&Menu::CreateHighScoreImage, this));
|
|
||||||
Engine::Get().SetImageSource("renderer_logo", "renderer_logo.png");
|
|
||||||
|
|
||||||
Engine::Get().SetImageSource("wave_up_tex", []() -> std::unique_ptr<Image> {
|
|
||||||
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
|
||||||
|
|
||||||
constexpr char btn_text[] = "[ ]";
|
|
||||||
|
|
||||||
int w, h;
|
|
||||||
font.CalculateBoundingBox(btn_text, w, h);
|
|
||||||
|
|
||||||
auto image = std::make_unique<Image>();
|
|
||||||
image->Create(w, h);
|
|
||||||
image->Clear({1, 1, 1, 0});
|
|
||||||
|
|
||||||
font.Print(0, 0, btn_text, image->GetBuffer(), image->GetWidth());
|
|
||||||
|
|
||||||
image->Compress();
|
|
||||||
return image;
|
|
||||||
});
|
|
||||||
|
|
||||||
Engine::Get().SetImageSource("version_tex", []() -> std::unique_ptr<Image> {
|
|
||||||
const Font* font = Engine::Get().GetSystemFont();
|
|
||||||
|
|
||||||
int w, h;
|
|
||||||
font->CalculateBoundingBox(kVersionStr, w, h);
|
|
||||||
|
|
||||||
auto image = std::make_unique<Image>();
|
|
||||||
image->Create(w, font->GetLineHeight());
|
|
||||||
image->Clear({1, 1, 1, 0});
|
|
||||||
|
|
||||||
font->Print(0, 0, kVersionStr, image->GetBuffer(), image->GetWidth());
|
|
||||||
|
|
||||||
image->Compress();
|
|
||||||
return image;
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Image> Menu::CreateMenuImage() {
|
std::unique_ptr<Image> Menu::CreateMenuImage() {
|
||||||
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,13 @@ class Menu {
|
||||||
Menu();
|
Menu();
|
||||||
~Menu();
|
~Menu();
|
||||||
|
|
||||||
|
bool PreInitialize();
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
void OnInputEvent(std::unique_ptr<eng::InputEvent> event);
|
void OnInputEvent(std::unique_ptr<eng::InputEvent> event);
|
||||||
|
|
||||||
void SetOptionEnabled(Option o, bool enable);
|
void SetOptionEnabled(Option o, bool enable);
|
||||||
|
void SetRendererType();
|
||||||
|
|
||||||
void Show();
|
void Show();
|
||||||
void Hide(base::Closure cb = nullptr);
|
void Hide(base::Closure cb = nullptr);
|
||||||
|
@ -145,9 +147,6 @@ class Menu {
|
||||||
|
|
||||||
Radio starting_wave_;
|
Radio starting_wave_;
|
||||||
Button wave_up_;
|
Button wave_up_;
|
||||||
Button wave_down_;
|
|
||||||
|
|
||||||
bool CreateRenderResources();
|
|
||||||
|
|
||||||
std::unique_ptr<eng::Image> CreateMenuImage();
|
std::unique_ptr<eng::Image> CreateMenuImage();
|
||||||
std::unique_ptr<eng::Image> CreateHighScoreImage();
|
std::unique_ptr<eng::Image> CreateHighScoreImage();
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "engine/font.h"
|
#include "engine/font.h"
|
||||||
#include "engine/input_event.h"
|
#include "engine/input_event.h"
|
||||||
#include "engine/sound.h"
|
|
||||||
|
|
||||||
#include "demo/demo.h"
|
#include "demo/demo.h"
|
||||||
|
|
||||||
|
@ -29,22 +28,20 @@ Player::Player() = default;
|
||||||
|
|
||||||
Player::~Player() = default;
|
Player::~Player() = default;
|
||||||
|
|
||||||
|
bool Player::PreInitialize() {
|
||||||
|
Engine::Get().SetImageSource("weapon_tex", "enemy_anims_flare_ok.png", true);
|
||||||
|
Engine::Get().SetImageSource("beam_tex", "enemy_ray_ok.png", true);
|
||||||
|
Engine::Get().SetImageSource("nuke_symbol_tex", "nuke_frames.png", true);
|
||||||
|
Engine::Get().SetImageSource("health_bead", "bead.png", true);
|
||||||
|
|
||||||
|
Engine::Get().AsyncLoadSound("laser", "laser.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("nuke", "nuke.mp3");
|
||||||
|
Engine::Get().AsyncLoadSound("no_nuke", "no_nuke.mp3");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Player::Initialize() {
|
bool Player::Initialize() {
|
||||||
if (!CreateRenderResources())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
laser_shot_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!laser_shot_sound_->Load("laser.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nuke_explosion_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!nuke_explosion_sound_->Load("nuke.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
no_nuke_sound_ = std::make_shared<Sound>();
|
|
||||||
if (!no_nuke_sound_->Load("no_nuke.mp3", false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SetupWeapons();
|
SetupWeapons();
|
||||||
|
|
||||||
Vector2f hb_pos = Engine::Get().GetScreenSize() / Vector2f(2, -2) +
|
Vector2f hb_pos = Engine::Get().GetScreenSize() / Vector2f(2, -2) +
|
||||||
|
@ -75,12 +72,12 @@ bool Player::Initialize() {
|
||||||
|
|
||||||
nuke_symbol_animator_.Attach(&nuke_symbol_);
|
nuke_symbol_animator_.Attach(&nuke_symbol_);
|
||||||
|
|
||||||
nuke_explosion_.SetSound(nuke_explosion_sound_);
|
nuke_explosion_.SetSound("nuke");
|
||||||
nuke_explosion_.SetVariate(false);
|
nuke_explosion_.SetVariate(false);
|
||||||
nuke_explosion_.SetSimulateStereo(false);
|
nuke_explosion_.SetSimulateStereo(false);
|
||||||
nuke_explosion_.SetMaxAplitude(0.8f);
|
nuke_explosion_.SetMaxAplitude(0.8f);
|
||||||
|
|
||||||
no_nuke_.SetSound(no_nuke_sound_);
|
no_nuke_.SetSound("no_nuke");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +303,7 @@ void Player::SetupWeapons() {
|
||||||
beam_animator_[i].SetBlending({1, 1, 1, 0}, 0.16f);
|
beam_animator_[i].SetBlending({1, 1, 1, 0}, 0.16f);
|
||||||
beam_animator_[i].Attach(&beam_[i]);
|
beam_animator_[i].Attach(&beam_[i]);
|
||||||
|
|
||||||
laser_shot_[i].SetSound(laser_shot_sound_);
|
laser_shot_[i].SetSound("laser");
|
||||||
laser_shot_[i].SetVariate(true);
|
laser_shot_[i].SetVariate(true);
|
||||||
laser_shot_[i].SetSimulateStereo(false);
|
laser_shot_[i].SetSimulateStereo(false);
|
||||||
laser_shot_[i].SetMaxAplitude(0.4f);
|
laser_shot_[i].SetMaxAplitude(0.4f);
|
||||||
|
@ -485,12 +482,3 @@ void Player::NavigateBack() {
|
||||||
Engine& engine = Engine::Get();
|
Engine& engine = Engine::Get();
|
||||||
static_cast<Demo*>(engine.GetGame())->EnterMenuState();
|
static_cast<Demo*>(engine.GetGame())->EnterMenuState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::CreateRenderResources() {
|
|
||||||
Engine::Get().SetImageSource("weapon_tex", "enemy_anims_flare_ok.png", true);
|
|
||||||
Engine::Get().SetImageSource("beam_tex", "enemy_ray_ok.png", true);
|
|
||||||
Engine::Get().SetImageSource("nuke_symbol_tex", "nuke_frames.png", true);
|
|
||||||
Engine::Get().SetImageSource("health_bead", "bead.png", true);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
class InputEvent;
|
class InputEvent;
|
||||||
class Sound;
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
|
@ -21,6 +20,7 @@ class Player {
|
||||||
Player();
|
Player();
|
||||||
~Player();
|
~Player();
|
||||||
|
|
||||||
|
bool PreInitialize();
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
void Update(float delta_time);
|
void Update(float delta_time);
|
||||||
|
@ -41,10 +41,6 @@ class Player {
|
||||||
int nuke_count() { return nuke_count_; }
|
int nuke_count() { return nuke_count_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<eng::Sound> nuke_explosion_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> no_nuke_sound_;
|
|
||||||
std::shared_ptr<eng::Sound> laser_shot_sound_;
|
|
||||||
|
|
||||||
eng::ImageQuad drag_sign_[2];
|
eng::ImageQuad drag_sign_[2];
|
||||||
eng::ImageQuad weapon_[2];
|
eng::ImageQuad weapon_[2];
|
||||||
eng::ImageQuad beam_[2];
|
eng::ImageQuad beam_[2];
|
||||||
|
@ -101,8 +97,6 @@ class Player {
|
||||||
bool ValidateDrag(int i);
|
bool ValidateDrag(int i);
|
||||||
|
|
||||||
void NavigateBack();
|
void NavigateBack();
|
||||||
|
|
||||||
bool CreateRenderResources();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEMO_PLAYER_H
|
#endif // DEMO_PLAYER_H
|
||||||
|
|
|
@ -21,8 +21,8 @@ SkyQuad::~SkyQuad() = default;
|
||||||
bool SkyQuad::Create(bool without_nebula) {
|
bool SkyQuad::Create(bool without_nebula) {
|
||||||
without_nebula_ = without_nebula;
|
without_nebula_ = without_nebula;
|
||||||
scale_ = Engine::Get().GetScreenSize();
|
scale_ = Engine::Get().GetScreenSize();
|
||||||
shader_ = Engine::Get().GetCustomShader(
|
shader_ =
|
||||||
without_nebula ? "sky_without_nebula" : "sky");
|
Engine::Get().GetShader(without_nebula ? "sky_without_nebula" : "sky");
|
||||||
|
|
||||||
color_animator_.Attach(this);
|
color_animator_.Attach(this);
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,6 @@
|
||||||
#include "engine/animatable.h"
|
#include "engine/animatable.h"
|
||||||
#include "engine/animator.h"
|
#include "engine/animator.h"
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
class Shader;
|
class Shader;
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -254,7 +254,8 @@ void AudioMixer::RenderAudio(float* output_buffer, size_t num_frames) {
|
||||||
|
|
||||||
ThreadPool::Get().PostTask(
|
ThreadPool::Get().PostTask(
|
||||||
HERE,
|
HERE,
|
||||||
std::bind(&AudioMixer::DoStream, this, *it, flags & kLoop));
|
std::bind(&AudioMixer::DoStream, this, *it, flags & kLoop),
|
||||||
|
true);
|
||||||
} else {
|
} else {
|
||||||
DLOG << "Mixer buffer underrun!";
|
DLOG << "Mixer buffer underrun!";
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "engine/renderer/texture.h"
|
#include "engine/renderer/texture.h"
|
||||||
#include "engine/renderer/vulkan/renderer_vulkan.h"
|
#include "engine/renderer/vulkan/renderer_vulkan.h"
|
||||||
#include "engine/shader_source.h"
|
#include "engine/shader_source.h"
|
||||||
|
#include "engine/sound.h"
|
||||||
#include "third_party/texture_compressor/texture_compressor.h"
|
#include "third_party/texture_compressor/texture_compressor.h"
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
@ -84,6 +85,7 @@ void Engine::Run() {
|
||||||
|
|
||||||
if (!renderer_->IsInitialzed()) {
|
if (!renderer_->IsInitialzed()) {
|
||||||
timer_.Reset();
|
timer_.Reset();
|
||||||
|
input_queue_.clear();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ void Engine::Initialize() {
|
||||||
|
|
||||||
thread_pool_.Initialize();
|
thread_pool_.Initialize();
|
||||||
|
|
||||||
CreateRenderer(RendererType::kVulkan);
|
CreateRendererInternal(RendererType::kVulkan);
|
||||||
|
|
||||||
// Normalize viewport.
|
// Normalize viewport.
|
||||||
if (GetScreenWidth() > GetScreenHeight()) {
|
if (GetScreenWidth() > GetScreenHeight()) {
|
||||||
|
@ -134,7 +136,11 @@ void Engine::Initialize() {
|
||||||
|
|
||||||
game_ = GameFactoryBase::CreateGame("");
|
game_ = GameFactoryBase::CreateGame("");
|
||||||
CHECK(game_) << "No game found to run.";
|
CHECK(game_) << "No game found to run.";
|
||||||
|
CHECK(game_->PreInitialize()) << "Failed to pre-initialize the game.";
|
||||||
|
|
||||||
|
// Create resources and let the game finalize initialization.
|
||||||
|
CreateRenderResources();
|
||||||
|
WaitForAsyncWork();
|
||||||
CHECK(game_->Initialize()) << "Failed to initialize the game.";
|
CHECK(game_->Initialize()) << "Failed to initialize the game.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,33 +211,12 @@ void Engine::RemoveAnimator(Animator* animator) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::CreateRenderer(RendererType type) {
|
void Engine::CreateRenderer(RendererType type) {
|
||||||
if ((dynamic_cast<RendererVulkan*>(renderer_.get()) &&
|
// Create a new renderer next cycle.
|
||||||
type == RendererType::kVulkan) ||
|
TaskRunner::TaskRunner::GetThreadLocalTaskRunner()->PostTask(
|
||||||
(dynamic_cast<RendererOpenGL*>(renderer_.get()) &&
|
HERE, std::bind(&Engine::CreateRendererInternal, this, type));
|
||||||
type == RendererType::kOpenGL))
|
TaskRunner::TaskRunner::GetThreadLocalTaskRunner()->PostTask(
|
||||||
return;
|
HERE, std::bind(&Engine::ContextLost, this));
|
||||||
|
input_queue_.clear();
|
||||||
if (type == RendererType::kVulkan)
|
|
||||||
renderer_ =
|
|
||||||
std::make_unique<RendererVulkan>(std::bind(&Engine::ContextLost, this));
|
|
||||||
else if (type == RendererType::kOpenGL)
|
|
||||||
renderer_ =
|
|
||||||
std::make_unique<RendererOpenGL>(std::bind(&Engine::ContextLost, this));
|
|
||||||
else
|
|
||||||
NOTREACHED;
|
|
||||||
|
|
||||||
bool result = renderer_->Initialize(platform_);
|
|
||||||
if (!result && type == RendererType::kVulkan) {
|
|
||||||
LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer.";
|
|
||||||
LOG << "Fallback to OpenGL renderer.";
|
|
||||||
CreateRenderer(RendererType::kOpenGL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
|
|
||||||
<< " renderer.";
|
|
||||||
|
|
||||||
CreateTextureCompressors();
|
|
||||||
ContextLost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererType Engine::GetRendererType() {
|
RendererType Engine::GetRendererType() {
|
||||||
|
@ -276,14 +261,8 @@ void Engine::SetImageSource(const std::string& asset_name,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& t = textures_[asset_name] = {CreateRenderResource<Texture>(),
|
textures_[asset_name] = {std::make_unique<Texture>(renderer_.get()),
|
||||||
create_image, persistent, 0};
|
create_image, persistent, 0};
|
||||||
|
|
||||||
if (persistent) {
|
|
||||||
auto image = create_image();
|
|
||||||
if (image)
|
|
||||||
t.texture->Update(std::move(image));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::RefreshImage(const std::string& asset_name) {
|
void Engine::RefreshImage(const std::string& asset_name) {
|
||||||
|
@ -297,8 +276,6 @@ void Engine::RefreshImage(const std::string& asset_name) {
|
||||||
auto image = it->second.create_image();
|
auto image = it->second.create_image();
|
||||||
if (image)
|
if (image)
|
||||||
it->second.texture->Update(std::move(image));
|
it->second.texture->Update(std::move(image));
|
||||||
else
|
|
||||||
it->second.texture->Destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,8 +287,11 @@ Texture* Engine::AcquireTexture(const std::string& asset_name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second.use_count++;
|
it->second.use_count++;
|
||||||
if (!it->second.texture->IsValid())
|
if (!it->second.texture->IsValid()) {
|
||||||
RefreshImage(it->first);
|
auto image = it->second.create_image();
|
||||||
|
if (image)
|
||||||
|
it->second.texture->Update(std::move(image));
|
||||||
|
}
|
||||||
return it->second.texture.get();
|
return it->second.texture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,40 +308,58 @@ void Engine::ReleaseTexture(const std::string& asset_name) {
|
||||||
it->second.texture->Destroy();
|
it->second.texture->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::LoadCustomShader(const std::string& asset_name,
|
void Engine::SetShaderSource(const std::string& asset_name,
|
||||||
const std::string& file_name) {
|
const std::string& file_name) {
|
||||||
if (shaders_.contains(asset_name)) {
|
if (shaders_.contains(asset_name)) {
|
||||||
DLOG << "Shader already exists: " << asset_name;
|
DLOG << "Shader already exists: " << asset_name;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& s = shaders_[asset_name] = {CreateRenderResource<Shader>(), file_name};
|
shaders_[asset_name] = {std::make_unique<Shader>(renderer_.get()), file_name};
|
||||||
|
|
||||||
auto source = std::make_unique<ShaderSource>();
|
|
||||||
if (!source->Load(file_name))
|
|
||||||
return;
|
|
||||||
s.shader->Create(std::move(source), quad_->vertex_description(),
|
|
||||||
quad_->primitive(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* Engine::GetCustomShader(const std::string& asset_name) {
|
Shader* Engine::GetShader(const std::string& asset_name) {
|
||||||
auto it = shaders_.find(asset_name);
|
auto it = shaders_.find(asset_name);
|
||||||
if (it == shaders_.end()) {
|
if (it == shaders_.end()) {
|
||||||
DLOG << "Shader not found: " << asset_name;
|
DLOG << "Shader not found: " << asset_name;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!it->second.shader->IsValid()) {
|
||||||
|
auto source = std::make_unique<ShaderSource>();
|
||||||
|
if (source->Load(it->second.file_name))
|
||||||
|
it->second.shader->Create(std::move(source), quad_->vertex_description(),
|
||||||
|
quad_->primitive(), false);
|
||||||
|
}
|
||||||
|
|
||||||
return it->second.shader.get();
|
return it->second.shader.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::RemoveCustomShader(const std::string& asset_name) {
|
void Engine::AsyncLoadSound(const std::string& asset_name,
|
||||||
auto it = shaders_.find(asset_name);
|
const std::string& file_name,
|
||||||
if (it == shaders_.end()) {
|
bool stream) {
|
||||||
DLOG << "Shader not found: " << asset_name;
|
if (audio_buses_.contains(asset_name)) {
|
||||||
|
DLOG << "AudioBus already exists: " << asset_name;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
shaders_.erase(it);
|
auto sound = std::make_shared<Sound>();
|
||||||
|
audio_buses_[asset_name] = sound;
|
||||||
|
|
||||||
|
++async_work_count_;
|
||||||
|
thread_pool_.PostTaskAndReply(
|
||||||
|
HERE, std::bind(&Sound::Load, sound, file_name, stream),
|
||||||
|
[&]() -> void { --async_work_count_; });
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<AudioBus> Engine::GetAudioBus(const std::string& asset_name) {
|
||||||
|
auto it = audio_buses_.find(asset_name);
|
||||||
|
if (it == audio_buses_.end()) {
|
||||||
|
DLOG << "AudioBus not found: " << asset_name;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<InputEvent> Engine::GetNextInputEvent() {
|
std::unique_ptr<InputEvent> Engine::GetNextInputEvent() {
|
||||||
|
@ -564,6 +562,35 @@ void Engine::AddInputEvent(std::unique_ptr<InputEvent> event) {
|
||||||
input_queue_.push_back(std::move(event));
|
input_queue_.push_back(std::move(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::CreateRendererInternal(RendererType type) {
|
||||||
|
if ((dynamic_cast<RendererVulkan*>(renderer_.get()) &&
|
||||||
|
type == RendererType::kVulkan) ||
|
||||||
|
(dynamic_cast<RendererOpenGL*>(renderer_.get()) &&
|
||||||
|
type == RendererType::kOpenGL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type == RendererType::kVulkan)
|
||||||
|
renderer_ =
|
||||||
|
std::make_unique<RendererVulkan>(std::bind(&Engine::ContextLost, this));
|
||||||
|
else if (type == RendererType::kOpenGL)
|
||||||
|
renderer_ =
|
||||||
|
std::make_unique<RendererOpenGL>(std::bind(&Engine::ContextLost, this));
|
||||||
|
else
|
||||||
|
NOTREACHED;
|
||||||
|
|
||||||
|
bool result = renderer_->Initialize(platform_);
|
||||||
|
if (!result && type == RendererType::kVulkan) {
|
||||||
|
LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer.";
|
||||||
|
LOG << "Fallback to OpenGL renderer.";
|
||||||
|
CreateRendererInternal(RendererType::kOpenGL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
|
||||||
|
<< " renderer.";
|
||||||
|
|
||||||
|
CreateTextureCompressors();
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::CreateTextureCompressors() {
|
void Engine::CreateTextureCompressors() {
|
||||||
tex_comp_alpha_.reset();
|
tex_comp_alpha_.reset();
|
||||||
tex_comp_opaque_.reset();
|
tex_comp_opaque_.reset();
|
||||||
|
@ -587,6 +614,15 @@ void Engine::CreateTextureCompressors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::ContextLost() {
|
void Engine::ContextLost() {
|
||||||
|
CreateRenderResources();
|
||||||
|
WaitForAsyncWork();
|
||||||
|
input_queue_.clear();
|
||||||
|
|
||||||
|
if (game_)
|
||||||
|
game_->ContextLost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::CreateRenderResources() {
|
||||||
quad_->SetRenderer(renderer_.get());
|
quad_->SetRenderer(renderer_.get());
|
||||||
pass_through_shader_->SetRenderer(renderer_.get());
|
pass_through_shader_->SetRenderer(renderer_.get());
|
||||||
solid_shader_->SetRenderer(renderer_.get());
|
solid_shader_->SetRenderer(renderer_.get());
|
||||||
|
@ -623,21 +659,45 @@ void Engine::ContextLost() {
|
||||||
|
|
||||||
for (auto& t : textures_) {
|
for (auto& t : textures_) {
|
||||||
t.second.texture->SetRenderer(renderer_.get());
|
t.second.texture->SetRenderer(renderer_.get());
|
||||||
RefreshImage(t.first);
|
if (t.second.persistent || t.second.use_count > 0) {
|
||||||
|
++async_work_count_;
|
||||||
|
thread_pool_.PostTaskAndReplyWithResult<std::unique_ptr<Image>>(
|
||||||
|
HERE, t.second.create_image,
|
||||||
|
[&,
|
||||||
|
ptr = t.second.texture.get()](std::unique_ptr<Image> image) -> void {
|
||||||
|
--async_work_count_;
|
||||||
|
if (image)
|
||||||
|
ptr->Update(std::move(image));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& s : shaders_) {
|
for (auto& s : shaders_) {
|
||||||
s.second.shader->SetRenderer(renderer_.get());
|
s.second.shader->SetRenderer(renderer_.get());
|
||||||
|
++async_work_count_;
|
||||||
|
thread_pool_.PostTaskAndReplyWithResult<std::unique_ptr<ShaderSource>>(
|
||||||
|
HERE,
|
||||||
|
[file_name = s.second.file_name]() -> std::unique_ptr<ShaderSource> {
|
||||||
auto source = std::make_unique<ShaderSource>();
|
auto source = std::make_unique<ShaderSource>();
|
||||||
if (source->Load(s.second.file_name))
|
if (!source->Load(file_name))
|
||||||
s.second.shader->Create(std::move(source), quad_->vertex_description(),
|
return nullptr;
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
[&, ptr = s.second.shader.get()](
|
||||||
|
std::unique_ptr<ShaderSource> source) -> void {
|
||||||
|
--async_work_count_;
|
||||||
|
if (source)
|
||||||
|
ptr->Create(std::move(source), quad_->vertex_description(),
|
||||||
quad_->primitive(), false);
|
quad_->primitive(), false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (game_)
|
void Engine::WaitForAsyncWork() {
|
||||||
game_->ContextLost();
|
while (async_work_count_ > 0) {
|
||||||
|
TaskRunner::GetThreadLocalTaskRunner()->RunTasks();
|
||||||
input_queue_.clear();
|
platform_->Update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::SetStatsVisible(bool visible) {
|
void Engine::SetStatsVisible(bool visible) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ class TextureCompressor;
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class Animator;
|
class Animator;
|
||||||
|
class AudioBus;
|
||||||
class AudioMixer;
|
class AudioMixer;
|
||||||
class Drawable;
|
class Drawable;
|
||||||
class Font;
|
class Font;
|
||||||
|
@ -61,11 +62,6 @@ class Engine : public PlatformObserver {
|
||||||
// Convert position form pixels to viewport coordinates.
|
// Convert position form pixels to viewport coordinates.
|
||||||
base::Vector2f ToPosition(const base::Vector2f& vec);
|
base::Vector2f ToPosition(const base::Vector2f& vec);
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
std::unique_ptr<T> CreateRenderResource() {
|
|
||||||
return std::unique_ptr<T>(static_cast<T*>(new T(renderer_.get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetImageSource(const std::string& asset_name,
|
void SetImageSource(const std::string& asset_name,
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
bool persistent = false);
|
bool persistent = false);
|
||||||
|
@ -78,10 +74,14 @@ class Engine : public PlatformObserver {
|
||||||
Texture* AcquireTexture(const std::string& asset_name);
|
Texture* AcquireTexture(const std::string& asset_name);
|
||||||
void ReleaseTexture(const std::string& asset_name);
|
void ReleaseTexture(const std::string& asset_name);
|
||||||
|
|
||||||
void LoadCustomShader(const std::string& asset_name,
|
void SetShaderSource(const std::string& asset_name,
|
||||||
const std::string& file_name);
|
const std::string& file_name);
|
||||||
Shader* GetCustomShader(const std::string& asset_name);
|
Shader* GetShader(const std::string& asset_name);
|
||||||
void RemoveCustomShader(const std::string& asset_name);
|
|
||||||
|
void AsyncLoadSound(const std::string& asset_name,
|
||||||
|
const std::string& file_name,
|
||||||
|
bool stream = false);
|
||||||
|
std::shared_ptr<AudioBus> GetAudioBus(const std::string& asset_name);
|
||||||
|
|
||||||
std::unique_ptr<InputEvent> GetNextInputEvent();
|
std::unique_ptr<InputEvent> GetNextInputEvent();
|
||||||
|
|
||||||
|
@ -191,9 +191,12 @@ class Engine : public PlatformObserver {
|
||||||
|
|
||||||
std::list<Animator*> animators_;
|
std::list<Animator*> animators_;
|
||||||
|
|
||||||
// Managed render resources mapped by asset name.
|
// Resources mapped by asset name.
|
||||||
std::unordered_map<std::string, TextureResource> textures_;
|
std::unordered_map<std::string, TextureResource> textures_;
|
||||||
std::unordered_map<std::string, ShaderResource> shaders_;
|
std::unordered_map<std::string, ShaderResource> shaders_;
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<AudioBus>> audio_buses_;
|
||||||
|
|
||||||
|
size_t async_work_count_ = 0;
|
||||||
|
|
||||||
std::unique_ptr<ImageQuad> stats_;
|
std::unique_ptr<ImageQuad> stats_;
|
||||||
|
|
||||||
|
@ -232,10 +235,16 @@ class Engine : public PlatformObserver {
|
||||||
void GainedFocus(bool from_interstitial_ad) final;
|
void GainedFocus(bool from_interstitial_ad) final;
|
||||||
void AddInputEvent(std::unique_ptr<InputEvent> event) final;
|
void AddInputEvent(std::unique_ptr<InputEvent> event) final;
|
||||||
|
|
||||||
|
void CreateRendererInternal(RendererType type);
|
||||||
|
|
||||||
void CreateTextureCompressors();
|
void CreateTextureCompressors();
|
||||||
|
|
||||||
void ContextLost();
|
void ContextLost();
|
||||||
|
|
||||||
|
void CreateRenderResources();
|
||||||
|
|
||||||
|
void WaitForAsyncWork();
|
||||||
|
|
||||||
void SetStatsVisible(bool visible);
|
void SetStatsVisible(bool visible);
|
||||||
std::unique_ptr<Image> PrintStats();
|
std::unique_ptr<Image> PrintStats();
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "engine/platform/asset_file.h"
|
#include "engine/platform/asset_file.h"
|
||||||
|
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
#define STBTT_STATIC
|
||||||
#include "../third_party/stb/stb_truetype.h"
|
#include "../third_party/stb/stb_truetype.h"
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
|
@ -8,6 +8,10 @@ class Game {
|
||||||
Game() = default;
|
Game() = default;
|
||||||
virtual ~Game() = default;
|
virtual ~Game() = default;
|
||||||
|
|
||||||
|
// Called before async-loading assets.
|
||||||
|
virtual bool PreInitialize() = 0;
|
||||||
|
|
||||||
|
// Called after resources are created.
|
||||||
virtual bool Initialize() = 0;
|
virtual bool Initialize() = 0;
|
||||||
|
|
||||||
virtual void Update(float delta_time) = 0;
|
virtual void Update(float delta_time) = 0;
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
// This 3rd party library is written in C and uses malloc, which means that we
|
// This 3rd party library is written in C and uses malloc, which means that we
|
||||||
// have to do the same.
|
// have to do the same.
|
||||||
#define STBI_NO_STDIO
|
|
||||||
#include "../third_party/stb/stb_image.h"
|
#include "../third_party/stb/stb_image.h"
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
|
|
@ -32,7 +32,6 @@ void ImageQuad::Create(const std::string& asset_name,
|
||||||
asset_name_ = asset_name;
|
asset_name_ = asset_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: typo
|
|
||||||
void ImageQuad::Destroy() {
|
void ImageQuad::Destroy() {
|
||||||
if (texture_) {
|
if (texture_) {
|
||||||
Engine::Get().ReleaseTexture(asset_name_);
|
Engine::Get().ReleaseTexture(asset_name_);
|
||||||
|
@ -51,7 +50,7 @@ void ImageQuad::AutoScale() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageQuad::SetCustomShader(const std::string& asset_name) {
|
void ImageQuad::SetCustomShader(const std::string& asset_name) {
|
||||||
custom_shader_ = Engine::Get().GetCustomShader(asset_name);
|
custom_shader_ = Engine::Get().GetShader(asset_name);
|
||||||
custom_uniforms_.clear();
|
custom_uniforms_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ Platform::Platform() {
|
||||||
shared_data_path_ = "./";
|
shared_data_path_ = "./";
|
||||||
LOG << "Shared data path: " << shared_data_path_.c_str();
|
LOG << "Shared data path: " << shared_data_path_.c_str();
|
||||||
|
|
||||||
|
XInitThreads();
|
||||||
|
|
||||||
bool res = CreateWindow(800, 1205);
|
bool res = CreateWindow(800, 1205);
|
||||||
CHECK(res) << "Failed to create window.";
|
CHECK(res) << "Failed to create window.";
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ RendererOpenGL::RendererOpenGL(base::Closure context_lost_cb)
|
||||||
: Renderer(context_lost_cb),
|
: Renderer(context_lost_cb),
|
||||||
main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()) {}
|
main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()) {}
|
||||||
#else
|
#else
|
||||||
RendererOpenGL::RendererOpenGL() = default;
|
RendererOpenGL::RendererOpenGL(base::Closure context_lost_cb)
|
||||||
|
: Renderer(context_lost_cb) {}
|
||||||
#endif // THREADED_RENDERING
|
#endif // THREADED_RENDERING
|
||||||
|
|
||||||
RendererOpenGL::~RendererOpenGL() {
|
RendererOpenGL::~RendererOpenGL() {
|
||||||
|
|
|
@ -414,10 +414,7 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
|
||||||
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
|
VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
|
||||||
task_runner_.PostTask(HERE, [&, mesh = mesh.release()]() {
|
task_runner_.Delete(HERE, std::move(mesh));
|
||||||
// Transfer mesh ownership to the background thread.
|
|
||||||
std::unique_ptr<Mesh> own(mesh);
|
|
||||||
});
|
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
|
|
||||||
return last_resource_id_;
|
return last_resource_id_;
|
||||||
|
@ -506,10 +503,7 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
|
||||||
0, VK_ACCESS_SHADER_READ_BIT,
|
0, VK_ACCESS_SHADER_READ_BIT,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
|
||||||
task_runner_.PostTask(HERE, [&, image = image.release()]() {
|
task_runner_.Delete(HERE, std::move(image));
|
||||||
// Transfer image ownership to the background thread.
|
|
||||||
std::unique_ptr<Image> own(image);
|
|
||||||
});
|
|
||||||
semaphore_.release();
|
semaphore_.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@ SoundPlayer::~SoundPlayer() {
|
||||||
Engine::Get().GetAudioMixer()->DestroyResource(resource_id_);
|
Engine::Get().GetAudioMixer()->DestroyResource(resource_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundPlayer::SetSound(const std::string& asset_name) {
|
||||||
|
sound_ = Engine::Get().GetAudioBus(asset_name);
|
||||||
|
}
|
||||||
|
|
||||||
void SoundPlayer::SetSound(std::shared_ptr<AudioBus> sound) {
|
void SoundPlayer::SetSound(std::shared_ptr<AudioBus> sound) {
|
||||||
sound_ = sound;
|
sound_ = sound;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define ENGINE_AUDIO_PLAYER_H
|
#define ENGINE_AUDIO_PLAYER_H
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "base/closure.h"
|
#include "base/closure.h"
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ class SoundPlayer {
|
||||||
SoundPlayer();
|
SoundPlayer();
|
||||||
~SoundPlayer();
|
~SoundPlayer();
|
||||||
|
|
||||||
|
void SetSound(const std::string& asset_name);
|
||||||
void SetSound(std::shared_ptr<AudioBus> sound);
|
void SetSound(std::shared_ptr<AudioBus> sound);
|
||||||
|
|
||||||
void Play(bool loop, float fade_in_duration = 0);
|
void Play(bool loop, float fade_in_duration = 0);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue