mirror of https://github.com/auygun/kaliber.git
Compare commits
3 Commits
7b637a95d9
...
e376b1bc17
Author | SHA1 | Date |
---|---|---|
Attila Uygun | e376b1bc17 | |
Attila Uygun | 76fb19ab3a | |
Attila Uygun | a39efa5d3c |
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -11,6 +11,7 @@
|
||||||
#include "engine/font.h"
|
#include "engine/font.h"
|
||||||
#include "engine/image.h"
|
#include "engine/image.h"
|
||||||
#include "engine/input_event.h"
|
#include "engine/input_event.h"
|
||||||
|
#include "engine/renderer/renderer.h"
|
||||||
#include "engine/sound.h"
|
#include "engine/sound.h"
|
||||||
|
|
||||||
#include "demo/demo.h"
|
#include "demo/demo.h"
|
||||||
|
@ -33,9 +34,10 @@ const Vector4f kColorNormal = {1, 1, 1, 1};
|
||||||
const Vector4f kColorHighlight = {20, 20, 20, 1};
|
const Vector4f kColorHighlight = {20, 20, 20, 1};
|
||||||
constexpr float kBlendingSpeed = 0.12f;
|
constexpr float kBlendingSpeed = 0.12f;
|
||||||
|
|
||||||
const Vector4f kColorSwitch[2] = {{0.003f, 0.91f, 0.99f, 1},
|
const std::array<Vector4f, 2> kColorSwitch = {Vector4f{0.003f, 0.91f, 0.99f, 1},
|
||||||
{0.33f, 0.47, 0.51f, 1}};
|
Vector4f{0.33f, 0.47, 0.51f, 1}};
|
||||||
|
|
||||||
|
const Vector4f kColorFadeIn = {1, 1, 1, 1};
|
||||||
const Vector4f kColorFadeOut = {1, 1, 1, 0};
|
const Vector4f kColorFadeOut = {1, 1, 1, 0};
|
||||||
constexpr float kFadeSpeed = 0.2f;
|
constexpr float kFadeSpeed = 0.2f;
|
||||||
|
|
||||||
|
@ -150,7 +152,8 @@ bool Menu::Initialize() {
|
||||||
}
|
}
|
||||||
game->saved_data().root()["audio"] = toggle_audio_.enabled();
|
game->saved_data().root()["audio"] = toggle_audio_.enabled();
|
||||||
},
|
},
|
||||||
true, game->saved_data().root().get("audio", Json::Value(true)).asBool());
|
true, game->saved_data().root().get("audio", Json::Value(true)).asBool(),
|
||||||
|
kColorFadeOut, kColorSwitch);
|
||||||
toggle_audio_.image().SetPosition(Engine::Get().GetScreenSize() *
|
toggle_audio_.image().SetPosition(Engine::Get().GetScreenSize() *
|
||||||
Vector2f(0, -0.25f));
|
Vector2f(0, -0.25f));
|
||||||
toggle_audio_.image().Scale(0.7f);
|
toggle_audio_.image().Scale(0.7f);
|
||||||
|
@ -162,7 +165,8 @@ bool Menu::Initialize() {
|
||||||
game->SetEnableMusic(toggle_music_.enabled());
|
game->SetEnableMusic(toggle_music_.enabled());
|
||||||
game->saved_data().root()["music"] = toggle_music_.enabled();
|
game->saved_data().root()["music"] = toggle_music_.enabled();
|
||||||
},
|
},
|
||||||
true, game->saved_data().root().get("music", Json::Value(true)).asBool());
|
true, game->saved_data().root().get("music", Json::Value(true)).asBool(),
|
||||||
|
kColorFadeOut, kColorSwitch);
|
||||||
toggle_music_.image().SetPosition(Engine::Get().GetScreenSize() *
|
toggle_music_.image().SetPosition(Engine::Get().GetScreenSize() *
|
||||||
Vector2f(0, -0.25f));
|
Vector2f(0, -0.25f));
|
||||||
toggle_music_.image().Scale(0.7f);
|
toggle_music_.image().Scale(0.7f);
|
||||||
|
@ -177,7 +181,8 @@ bool Menu::Initialize() {
|
||||||
game->saved_data().root()["vibration"] = toggle_vibration_.enabled();
|
game->saved_data().root()["vibration"] = toggle_vibration_.enabled();
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
game->saved_data().root().get("vibration", Json::Value(true)).asBool());
|
game->saved_data().root().get("vibration", Json::Value(true)).asBool(),
|
||||||
|
kColorFadeOut, kColorSwitch);
|
||||||
toggle_vibration_.image().SetPosition(Engine::Get().GetScreenSize() *
|
toggle_vibration_.image().SetPosition(Engine::Get().GetScreenSize() *
|
||||||
Vector2f(0, -0.25f));
|
Vector2f(0, -0.25f));
|
||||||
toggle_vibration_.image().Scale(0.7f);
|
toggle_vibration_.image().Scale(0.7f);
|
||||||
|
@ -188,6 +193,21 @@ bool Menu::Initialize() {
|
||||||
toggle_vibration_.image().Translate(
|
toggle_vibration_.image().Translate(
|
||||||
{toggle_music_.image().GetSize().x / 2, 0});
|
{toggle_music_.image().GetSize().x / 2, 0});
|
||||||
|
|
||||||
|
renderer_type_.Create(
|
||||||
|
"renderer_logo", {2, 1}, 0, 1,
|
||||||
|
[&] {
|
||||||
|
Engine::Get().CreateRenderer(renderer_type_.enabled()
|
||||||
|
? RendererType::kVulkan
|
||||||
|
: RendererType::kOpenGL);
|
||||||
|
renderer_type_.SetEnabled(
|
||||||
|
(Engine::Get().GetRendererType() == RendererType::kVulkan));
|
||||||
|
},
|
||||||
|
true, Engine::Get().GetRendererType() == RendererType::kVulkan,
|
||||||
|
kColorFadeOut, {Vector4f{1, 1, 1, 1}, Vector4f{1, 1, 1, 1}});
|
||||||
|
renderer_type_.image().PlaceToBottomOf(toggle_music_.image());
|
||||||
|
renderer_type_.image().Translate(toggle_music_.image().GetPosition() *
|
||||||
|
Vector2f(0, 1.1f));
|
||||||
|
|
||||||
high_score_value_ = game->GetHighScore();
|
high_score_value_ = game->GetHighScore();
|
||||||
|
|
||||||
high_score_.Create("high_score_tex");
|
high_score_.Create("high_score_tex");
|
||||||
|
@ -226,7 +246,7 @@ bool Menu::Initialize() {
|
||||||
starting_wave_.image().SetFrame(start_from_wave_ / 3);
|
starting_wave_.image().SetFrame(start_from_wave_ / 3);
|
||||||
click_.Play(false);
|
click_.Play(false);
|
||||||
},
|
},
|
||||||
false, true);
|
false, true, kColorFadeOut, kColorSwitch);
|
||||||
wave_up_.image().Scale(1.5f);
|
wave_up_.image().Scale(1.5f);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -236,6 +256,7 @@ void Menu::OnInputEvent(std::unique_ptr<InputEvent> event) {
|
||||||
if (toggle_audio_.OnInputEvent(event.get()) ||
|
if (toggle_audio_.OnInputEvent(event.get()) ||
|
||||||
toggle_music_.OnInputEvent(event.get()) ||
|
toggle_music_.OnInputEvent(event.get()) ||
|
||||||
toggle_vibration_.OnInputEvent(event.get()) ||
|
toggle_vibration_.OnInputEvent(event.get()) ||
|
||||||
|
renderer_type_.OnInputEvent(event.get()) ||
|
||||||
(wave_up_.image().IsVisible() && wave_up_.OnInputEvent(event.get())))
|
(wave_up_.image().IsVisible() && wave_up_.OnInputEvent(event.get())))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -350,6 +371,7 @@ void Menu::Show() {
|
||||||
toggle_audio_.Show();
|
toggle_audio_.Show();
|
||||||
toggle_music_.Show();
|
toggle_music_.Show();
|
||||||
toggle_vibration_.Show();
|
toggle_vibration_.Show();
|
||||||
|
renderer_type_.Show();
|
||||||
|
|
||||||
Demo* game = static_cast<Demo*>(Engine::Get().GetGame());
|
Demo* game = static_cast<Demo*>(Engine::Get().GetGame());
|
||||||
|
|
||||||
|
@ -410,6 +432,7 @@ void Menu::Hide(Closure cb) {
|
||||||
toggle_audio_.Hide();
|
toggle_audio_.Hide();
|
||||||
toggle_music_.Hide();
|
toggle_music_.Hide();
|
||||||
toggle_vibration_.Hide();
|
toggle_vibration_.Hide();
|
||||||
|
renderer_type_.Hide();
|
||||||
|
|
||||||
if (starting_wave_.image().IsVisible()) {
|
if (starting_wave_.image().IsVisible()) {
|
||||||
starting_wave_.Hide();
|
starting_wave_.Hide();
|
||||||
|
@ -425,6 +448,7 @@ bool Menu::CreateRenderResources() {
|
||||||
Engine::Get().SetImageSource("buttons_tex", "menu_icons.png");
|
Engine::Get().SetImageSource("buttons_tex", "menu_icons.png");
|
||||||
Engine::Get().SetImageSource("high_score_tex",
|
Engine::Get().SetImageSource("high_score_tex",
|
||||||
std::bind(&Menu::CreateHighScoreImage, this));
|
std::bind(&Menu::CreateHighScoreImage, this));
|
||||||
|
Engine::Get().SetImageSource("renderer_logo", "renderer_logo.png");
|
||||||
|
|
||||||
Engine::Get().SetImageSource("wave_up_tex", []() -> std::unique_ptr<Image> {
|
Engine::Get().SetImageSource("wave_up_tex", []() -> std::unique_ptr<Image> {
|
||||||
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
const Font& font = static_cast<Demo*>(Engine::Get().GetGame())->GetFont();
|
||||||
|
@ -520,16 +544,20 @@ void Menu::Button::Create(const std::string& asset_name,
|
||||||
int frame2,
|
int frame2,
|
||||||
Closure pressed_cb,
|
Closure pressed_cb,
|
||||||
bool switch_control,
|
bool switch_control,
|
||||||
bool enabled) {
|
bool enabled,
|
||||||
|
const Vector4f& fade_out_color,
|
||||||
|
const std::array<Vector4f, 2>& switch_color) {
|
||||||
frame1_ = frame1;
|
frame1_ = frame1;
|
||||||
frame2_ = frame2;
|
frame2_ = frame2;
|
||||||
pressed_cb_ = std::move(pressed_cb);
|
pressed_cb_ = std::move(pressed_cb);
|
||||||
switch_control_ = switch_control;
|
switch_control_ = switch_control;
|
||||||
enabled_ = enabled;
|
enabled_ = enabled;
|
||||||
|
fade_out_color_ = fade_out_color;
|
||||||
|
switch_color_ = switch_color;
|
||||||
|
|
||||||
image_.Create(asset_name, num_frames);
|
image_.Create(asset_name, num_frames);
|
||||||
image_.SetFrame(enabled ? frame1 : frame2);
|
image_.SetFrame(enabled ? frame1 : frame2);
|
||||||
image_.SetColor(kColorFadeOut);
|
image_.SetColor(fade_out_color_);
|
||||||
image_.SetZOrder(41);
|
image_.SetZOrder(41);
|
||||||
image_.SetVisible(false);
|
image_.SetVisible(false);
|
||||||
|
|
||||||
|
@ -562,14 +590,14 @@ bool Menu::Button::OnInputEvent(eng::InputEvent* event) {
|
||||||
|
|
||||||
void Menu::Button::Show() {
|
void Menu::Button::Show() {
|
||||||
animator_.SetVisible(true);
|
animator_.SetVisible(true);
|
||||||
animator_.SetBlending(enabled_ ? kColorSwitch[0] : kColorSwitch[1],
|
animator_.SetBlending(enabled_ ? switch_color_[0] : switch_color_[1],
|
||||||
kBlendingSpeed);
|
kBlendingSpeed);
|
||||||
animator_.Play(Animator::kBlending, false);
|
animator_.Play(Animator::kBlending, false);
|
||||||
animator_.SetEndCallback(Animator::kBlending, nullptr);
|
animator_.SetEndCallback(Animator::kBlending, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::Button::Hide() {
|
void Menu::Button::Hide() {
|
||||||
animator_.SetBlending(kColorFadeOut, kBlendingSpeed);
|
animator_.SetBlending(fade_out_color_, kBlendingSpeed);
|
||||||
animator_.Play(Animator::kBlending, false);
|
animator_.Play(Animator::kBlending, false);
|
||||||
animator_.SetEndCallback(Animator::kBlending,
|
animator_.SetEndCallback(Animator::kBlending,
|
||||||
[&]() -> void { animator_.SetVisible(false); });
|
[&]() -> void { animator_.SetVisible(false); });
|
||||||
|
@ -579,7 +607,7 @@ void Menu::Button::SetEnabled(bool enable) {
|
||||||
if (switch_control_) {
|
if (switch_control_) {
|
||||||
enabled_ = enable;
|
enabled_ = enable;
|
||||||
image_.SetFrame(enabled_ ? frame1_ : frame2_);
|
image_.SetFrame(enabled_ ? frame1_ : frame2_);
|
||||||
image_.SetColor(enabled_ ? kColorSwitch[0] : kColorSwitch[1]);
|
image_.SetColor(enabled_ ? switch_color_[0] : switch_color_[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,17 @@ class Menu {
|
||||||
int frame2,
|
int frame2,
|
||||||
base::Closure pressed_cb,
|
base::Closure pressed_cb,
|
||||||
bool switch_control,
|
bool switch_control,
|
||||||
bool enabled);
|
bool enabled,
|
||||||
|
const base::Vector4f& fade_out_color,
|
||||||
|
const std::array<base::Vector4f, 2>& switch_color);
|
||||||
|
|
||||||
bool OnInputEvent(eng::InputEvent* event);
|
bool OnInputEvent(eng::InputEvent* event);
|
||||||
|
|
||||||
void Show();
|
void Show();
|
||||||
void Hide();
|
void Hide();
|
||||||
|
|
||||||
|
void SetEnabled(bool enable);
|
||||||
|
|
||||||
eng::ImageQuad& image() { return image_; };
|
eng::ImageQuad& image() { return image_; };
|
||||||
|
|
||||||
bool enabled() const { return enabled_; }
|
bool enabled() const { return enabled_; }
|
||||||
|
@ -77,7 +81,8 @@ class Menu {
|
||||||
bool enabled_ = false;
|
bool enabled_ = false;
|
||||||
base::Vector2f tap_pos_[2] = {{0, 0}, {0, 0}};
|
base::Vector2f tap_pos_[2] = {{0, 0}, {0, 0}};
|
||||||
|
|
||||||
void SetEnabled(bool enable);
|
base::Vector4f fade_out_color_;
|
||||||
|
std::array<base::Vector4f, 2> switch_color_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Radio {
|
class Radio {
|
||||||
|
@ -126,6 +131,7 @@ class Menu {
|
||||||
Button toggle_audio_;
|
Button toggle_audio_;
|
||||||
Button toggle_music_;
|
Button toggle_music_;
|
||||||
Button toggle_vibration_;
|
Button toggle_vibration_;
|
||||||
|
Button renderer_type_;
|
||||||
|
|
||||||
size_t high_score_value_ = 0;
|
size_t high_score_value_ = 0;
|
||||||
|
|
||||||
|
|
|
@ -11,28 +11,28 @@ namespace eng {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::array<std::unique_ptr<T[]>, 2> Deinterleave(size_t num_channels,
|
std::array<std::unique_ptr<T[]>, 2> Deinterleave(
|
||||||
size_t num_samples,
|
size_t num_channels,
|
||||||
float* input_buffer) {
|
size_t num_samples,
|
||||||
|
std::unique_ptr<float[]> source_buffer) {
|
||||||
std::array<std::unique_ptr<T[]>, 2> channels;
|
std::array<std::unique_ptr<T[]>, 2> channels;
|
||||||
|
|
||||||
if (num_channels == 1) {
|
if (num_channels == 1) {
|
||||||
// Single channel.
|
|
||||||
if constexpr (std::is_same<float, T>::value) {
|
if constexpr (std::is_same<float, T>::value) {
|
||||||
channels[0] = std::make_unique<T[]>(num_samples);
|
// Passthrough
|
||||||
memcpy(channels[0].get(), input_buffer, num_samples * sizeof(float));
|
channels[0] = std::move(source_buffer);
|
||||||
} else {
|
} else {
|
||||||
channels[0] = std::make_unique<T[]>(num_samples);
|
channels[0] = std::make_unique<T[]>(num_samples);
|
||||||
for (int i = 0; i < num_samples; ++i)
|
for (int i = 0; i < num_samples; ++i)
|
||||||
channels[0].get()[i] = static_cast<T>(input_buffer[i]);
|
channels[0].get()[i] = static_cast<T>(source_buffer.get()[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Deinterleave into separate channels.
|
// Deinterleave into separate channels.
|
||||||
channels[0] = std::make_unique<T[]>(num_samples);
|
channels[0] = std::make_unique<T[]>(num_samples);
|
||||||
channels[1] = std::make_unique<T[]>(num_samples);
|
channels[1] = std::make_unique<T[]>(num_samples);
|
||||||
for (size_t i = 0, j = 0; i < num_samples * 2; i += 2) {
|
for (size_t i = 0, j = 0; i < num_samples * 2; i += 2) {
|
||||||
channels[0].get()[j] = static_cast<T>(input_buffer[i]);
|
channels[0].get()[j] = static_cast<T>(source_buffer.get()[i]);
|
||||||
channels[1].get()[j++] = static_cast<T>(input_buffer[i + 1]);
|
channels[1].get()[j++] = static_cast<T>(source_buffer.get()[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,15 +59,15 @@ void AudioBus::SetAudioConfig(size_t num_channels, size_t sample_rate) {
|
||||||
sample_rate_ = sample_rate;
|
sample_rate_ = sample_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBus::FromInterleaved(std::unique_ptr<float[]> input_buffer,
|
void AudioBus::FromInterleaved(std::unique_ptr<float[]> source_buffer,
|
||||||
size_t samples_per_channel) {
|
size_t samples_per_channel) {
|
||||||
auto channels = Deinterleave<float>(num_channels_, samples_per_channel,
|
auto channels = Deinterleave<float>(num_channels_, samples_per_channel,
|
||||||
input_buffer.get());
|
std::move(source_buffer));
|
||||||
|
|
||||||
size_t hw_sample_rate = Engine::Get().GetAudioHardwareSampleRate();
|
size_t hw_sample_rate = Engine::Get().GetAudioHardwareSampleRate();
|
||||||
|
|
||||||
if (hw_sample_rate == sample_rate_) {
|
if (hw_sample_rate == sample_rate_) {
|
||||||
// No need for resmapling.
|
// Passthrough
|
||||||
channel_data_[0] = std::move(channels[0]);
|
channel_data_[0] = std::move(channels[0]);
|
||||||
if (num_channels_ == 2)
|
if (num_channels_ == 2)
|
||||||
channel_data_[1] = std::move(channels[1]);
|
channel_data_[1] = std::move(channels[1]);
|
||||||
|
|
|
@ -7,6 +7,10 @@ namespace eng {
|
||||||
|
|
||||||
class SincResampler;
|
class SincResampler;
|
||||||
|
|
||||||
|
// Represents a sequence of audio samples for each channels. The data layout is
|
||||||
|
// planar as opposed to interleaved. The memory for the data is allocated and
|
||||||
|
// owned by the AudioBus. Max two channels are supported. An AudioBus with one
|
||||||
|
// channel is mono, with two channels is stereo.
|
||||||
class AudioBus {
|
class AudioBus {
|
||||||
public:
|
public:
|
||||||
AudioBus();
|
AudioBus();
|
||||||
|
@ -28,7 +32,11 @@ class AudioBus {
|
||||||
protected:
|
protected:
|
||||||
void SetAudioConfig(size_t num_channels, size_t sample_rate);
|
void SetAudioConfig(size_t num_channels, size_t sample_rate);
|
||||||
|
|
||||||
void FromInterleaved(std::unique_ptr<float[]> input_buffer,
|
// Overwrites the sample values stored in this AudioBus instance with values
|
||||||
|
// from a given interleaved source_buffer. The expected layout of the
|
||||||
|
// source_buffer is [ch0, ch1, ch0, ch1, ...]. A sample-rate conversion to the
|
||||||
|
// system sample-rate will be made if it doesn't match.
|
||||||
|
void FromInterleaved(std::unique_ptr<float[]> source_buffer,
|
||||||
size_t samples_per_channel);
|
size_t samples_per_channel);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "base/closure.h"
|
#include "base/closure.h"
|
||||||
#include "engine/audio/audio_sink_delegate.h"
|
#include "engine/audio/audio_sink.h"
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class TaskRunner;
|
class TaskRunner;
|
||||||
|
@ -22,7 +22,7 @@ class AudioBus;
|
||||||
// Mix and render audio with low overhead. A platform specific AudioSink
|
// Mix and render audio with low overhead. A platform specific AudioSink
|
||||||
// implementation is expected to periodically call RenderAudio() in a background
|
// implementation is expected to periodically call RenderAudio() in a background
|
||||||
// thread.
|
// thread.
|
||||||
class AudioMixer : public AudioSinkDelegate {
|
class AudioMixer : public AudioSink::Delegate {
|
||||||
public:
|
public:
|
||||||
AudioMixer();
|
AudioMixer();
|
||||||
~AudioMixer();
|
~AudioMixer();
|
||||||
|
@ -91,7 +91,7 @@ class AudioMixer : public AudioSinkDelegate {
|
||||||
|
|
||||||
bool audio_enabled_ = true;
|
bool audio_enabled_ = true;
|
||||||
|
|
||||||
// AudioSinkDelegate implementation
|
// AudioSink::Delegate implementation
|
||||||
int GetChannelCount() final { return kChannelCount; }
|
int GetChannelCount() final { return kChannelCount; }
|
||||||
void RenderAudio(float* output_buffer, size_t num_frames) final;
|
void RenderAudio(float* output_buffer, size_t num_frames) final;
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,19 @@
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
// Models an audio sink sending mixed audio to the audio driver. Audio data from
|
// Models an audio sink sending mixed audio to the audio driver. Audio data from
|
||||||
// the mixer source is delivered on a pull model using AudioSinkDelegate.
|
// the mixer source is delivered on a pull model using Delegate.
|
||||||
class AudioSink {
|
class AudioSink {
|
||||||
public:
|
public:
|
||||||
|
class Delegate {
|
||||||
|
public:
|
||||||
|
Delegate() = default;
|
||||||
|
virtual ~Delegate() = default;
|
||||||
|
|
||||||
|
virtual int GetChannelCount() = 0;
|
||||||
|
|
||||||
|
virtual void RenderAudio(float* output_buffer, size_t num_frames) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
AudioSink() = default;
|
AudioSink() = default;
|
||||||
virtual ~AudioSink() = default;
|
virtual ~AudioSink() = default;
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,12 @@
|
||||||
#include <alsa/asoundlib.h>
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "engine/audio/audio_sink_delegate.h"
|
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
AudioSinkAlsa::AudioSinkAlsa(AudioSinkDelegate* delegate)
|
AudioSinkAlsa::AudioSinkAlsa(AudioSink::Delegate* delegate)
|
||||||
: delegate_(delegate) {}
|
: delegate_(delegate) {}
|
||||||
|
|
||||||
AudioSinkAlsa::~AudioSinkAlsa() {
|
AudioSinkAlsa::~AudioSinkAlsa() {
|
||||||
|
|
|
@ -10,11 +10,9 @@ typedef struct _snd_pcm snd_pcm_t;
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class AudioSinkDelegate;
|
|
||||||
|
|
||||||
class AudioSinkAlsa final : public AudioSink {
|
class AudioSinkAlsa final : public AudioSink {
|
||||||
public:
|
public:
|
||||||
AudioSinkAlsa(AudioSinkDelegate* delegate);
|
AudioSinkAlsa(AudioSink::Delegate* delegate);
|
||||||
~AudioSinkAlsa() final;
|
~AudioSinkAlsa() final;
|
||||||
|
|
||||||
bool Initialize() final;
|
bool Initialize() final;
|
||||||
|
@ -36,7 +34,7 @@ class AudioSinkAlsa final : public AudioSink {
|
||||||
size_t sample_rate_ = 0;
|
size_t sample_rate_ = 0;
|
||||||
size_t period_size_ = 0;
|
size_t period_size_ = 0;
|
||||||
|
|
||||||
AudioSinkDelegate* delegate_ = nullptr;
|
AudioSink::Delegate* delegate_ = nullptr;
|
||||||
|
|
||||||
void StartAudioThread();
|
void StartAudioThread();
|
||||||
void TerminateAudioThread();
|
void TerminateAudioThread();
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef ENGINE_AUDIO_AUDIO_SINK_DELEGATE_H
|
|
||||||
#define ENGINE_AUDIO_AUDIO_SINK_DELEGATE_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
namespace eng {
|
|
||||||
|
|
||||||
class AudioSinkDelegate {
|
|
||||||
public:
|
|
||||||
AudioSinkDelegate() = default;
|
|
||||||
virtual ~AudioSinkDelegate() = default;
|
|
||||||
|
|
||||||
virtual int GetChannelCount() = 0;
|
|
||||||
|
|
||||||
virtual void RenderAudio(float* output_buffer, size_t num_frames) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace eng
|
|
||||||
|
|
||||||
#endif // ENGINE_AUDIO_AUDIO_SINK_DELEGATE_H
|
|
|
@ -1,14 +1,13 @@
|
||||||
#include "engine/audio/audio_sink_oboe.h"
|
#include "engine/audio/audio_sink_oboe.h"
|
||||||
|
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "engine/audio/audio_sink_delegate.h"
|
|
||||||
#include "third_party/oboe/include/oboe/Oboe.h"
|
#include "third_party/oboe/include/oboe/Oboe.h"
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
AudioSinkOboe::AudioSinkOboe(AudioSinkDelegate* delegate)
|
AudioSinkOboe::AudioSinkOboe(AudioSink::Delegate* delegate)
|
||||||
: callback_(std::make_unique<StreamCallback>(this)), delegate_(delegate) {}
|
: callback_(std::make_unique<StreamCallback>(this)), delegate_(delegate) {}
|
||||||
|
|
||||||
AudioSinkOboe::~AudioSinkOboe() {
|
AudioSinkOboe::~AudioSinkOboe() {
|
||||||
|
|
|
@ -10,11 +10,9 @@
|
||||||
|
|
||||||
namespace eng {
|
namespace eng {
|
||||||
|
|
||||||
class AudioSinkDelegate;
|
|
||||||
|
|
||||||
class AudioSinkOboe final : public AudioSink {
|
class AudioSinkOboe final : public AudioSink {
|
||||||
public:
|
public:
|
||||||
AudioSinkOboe(AudioSinkDelegate* delegate);
|
AudioSinkOboe(AudioSink::Delegate* delegate);
|
||||||
~AudioSinkOboe() final;
|
~AudioSinkOboe() final;
|
||||||
|
|
||||||
bool Initialize() final;
|
bool Initialize() final;
|
||||||
|
@ -44,7 +42,7 @@ class AudioSinkOboe final : public AudioSink {
|
||||||
oboe::ManagedStream stream_;
|
oboe::ManagedStream stream_;
|
||||||
std::unique_ptr<StreamCallback> callback_;
|
std::unique_ptr<StreamCallback> callback_;
|
||||||
|
|
||||||
AudioSinkDelegate* delegate_ = nullptr;
|
AudioSink::Delegate* delegate_ = nullptr;
|
||||||
|
|
||||||
bool RestartStream();
|
bool RestartStream();
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,7 +106,7 @@ void Engine::Initialize() {
|
||||||
|
|
||||||
thread_pool_.Initialize();
|
thread_pool_.Initialize();
|
||||||
|
|
||||||
CreateRenderer(true);
|
CreateRenderer(RendererType::kVulkan);
|
||||||
|
|
||||||
// Normalize viewport.
|
// Normalize viewport.
|
||||||
if (GetScreenWidth() > GetScreenHeight()) {
|
if (GetScreenWidth() > GetScreenHeight()) {
|
||||||
|
@ -201,23 +201,27 @@ void Engine::RemoveAnimator(Animator* animator) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::CreateRenderer(bool vulkan) {
|
void Engine::CreateRenderer(RendererType type) {
|
||||||
if ((dynamic_cast<RendererVulkan*>(renderer_.get()) && vulkan) ||
|
if ((dynamic_cast<RendererVulkan*>(renderer_.get()) &&
|
||||||
(dynamic_cast<RendererOpenGL*>(renderer_.get()) && !vulkan))
|
type == RendererType::kVulkan) ||
|
||||||
|
(dynamic_cast<RendererOpenGL*>(renderer_.get()) &&
|
||||||
|
type == RendererType::kOpenGL))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vulkan)
|
if (type == RendererType::kVulkan)
|
||||||
renderer_ =
|
renderer_ =
|
||||||
std::make_unique<RendererVulkan>(std::bind(&Engine::ContextLost, this));
|
std::make_unique<RendererVulkan>(std::bind(&Engine::ContextLost, this));
|
||||||
else
|
else if (type == RendererType::kOpenGL)
|
||||||
renderer_ =
|
renderer_ =
|
||||||
std::make_unique<RendererOpenGL>(std::bind(&Engine::ContextLost, this));
|
std::make_unique<RendererOpenGL>(std::bind(&Engine::ContextLost, this));
|
||||||
|
else
|
||||||
|
NOTREACHED;
|
||||||
|
|
||||||
bool result = renderer_->Initialize(platform_);
|
bool result = renderer_->Initialize(platform_);
|
||||||
if (!result && vulkan) {
|
if (!result && type == RendererType::kVulkan) {
|
||||||
LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer.";
|
LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer.";
|
||||||
LOG << "Fallback to OpenGL renderer.";
|
LOG << "Fallback to OpenGL renderer.";
|
||||||
CreateRenderer(false);
|
CreateRenderer(RendererType::kOpenGL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
|
CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
|
||||||
|
@ -227,6 +231,12 @@ void Engine::CreateRenderer(bool vulkan) {
|
||||||
ContextLost();
|
ContextLost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RendererType Engine::GetRendererType() {
|
||||||
|
if (renderer_)
|
||||||
|
return renderer_->GetRendererType();
|
||||||
|
return RendererType::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::Exit() {
|
void Engine::Exit() {
|
||||||
platform_->Exit();
|
platform_->Exit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,18 @@ namespace eng {
|
||||||
|
|
||||||
class Animator;
|
class Animator;
|
||||||
class AudioMixer;
|
class AudioMixer;
|
||||||
|
class Drawable;
|
||||||
class Font;
|
class Font;
|
||||||
class Game;
|
class Game;
|
||||||
class Drawable;
|
class Geometry;
|
||||||
class InputEvent;
|
|
||||||
class Image;
|
class Image;
|
||||||
class ImageQuad;
|
class ImageQuad;
|
||||||
|
class InputEvent;
|
||||||
|
class Platform;
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class Geometry;
|
|
||||||
class Shader;
|
class Shader;
|
||||||
class Texture;
|
class Texture;
|
||||||
class Platform;
|
enum class RendererType;
|
||||||
|
|
||||||
class Engine : public PlatformObserver {
|
class Engine : public PlatformObserver {
|
||||||
public:
|
public:
|
||||||
|
@ -49,7 +50,8 @@ class Engine : public PlatformObserver {
|
||||||
void AddAnimator(Animator* animator);
|
void AddAnimator(Animator* animator);
|
||||||
void RemoveAnimator(Animator* animator);
|
void RemoveAnimator(Animator* animator);
|
||||||
|
|
||||||
void CreateRenderer(bool vulkan);
|
void CreateRenderer(RendererType type);
|
||||||
|
RendererType GetRendererType();
|
||||||
|
|
||||||
void Exit();
|
void Exit();
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,8 @@ class RendererOpenGL final : public Renderer {
|
||||||
|
|
||||||
const char* GetDebugName() final { return "OpenGL"; }
|
const char* GetDebugName() final { return "OpenGL"; }
|
||||||
|
|
||||||
|
RendererType GetRendererType() final { return RendererType::kOpenGL; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct GeometryOpenGL {
|
struct GeometryOpenGL {
|
||||||
struct Element {
|
struct Element {
|
||||||
|
|
|
@ -15,6 +15,8 @@ class ShaderSource;
|
||||||
class Mesh;
|
class Mesh;
|
||||||
class Platform;
|
class Platform;
|
||||||
|
|
||||||
|
enum class RendererType { kUnknown, kVulkan, kOpenGL };
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
const unsigned kInvalidId = 0;
|
const unsigned kInvalidId = 0;
|
||||||
|
@ -82,6 +84,8 @@ class Renderer {
|
||||||
|
|
||||||
virtual const char* GetDebugName() = 0;
|
virtual const char* GetDebugName() = 0;
|
||||||
|
|
||||||
|
virtual RendererType GetRendererType() { return RendererType::kUnknown; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct TextureCompression {
|
struct TextureCompression {
|
||||||
unsigned etc1 : 1;
|
unsigned etc1 : 1;
|
||||||
|
|
|
@ -69,6 +69,8 @@ class RendererVulkan final : public Renderer {
|
||||||
|
|
||||||
const char* GetDebugName() final { return "Vulkan"; }
|
const char* GetDebugName() final { return "Vulkan"; }
|
||||||
|
|
||||||
|
RendererType GetRendererType() final { return RendererType::kVulkan; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// VkBuffer or VkImage with allocator.
|
// VkBuffer or VkImage with allocator.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
Loading…
Reference in New Issue