Compare commits

..

4 Commits

Author SHA1 Message Date
Attila Uygun 9680ca975c PlatformObserver wip 2023-05-25 16:02:00 +02:00
Attila Uygun b1c2e3f0d4 for android 2023-05-25 15:33:05 +02:00
Attila Uygun aca0213b0a crash fix 2023-05-25 10:48:19 +02:00
Attila Uygun a7ea09b149 move renderer ownership to engine (WIP) 2023-05-25 07:43:09 +02:00
18 changed files with 260 additions and 172 deletions

View File

@ -74,6 +74,7 @@ add_library(kaliber SHARED
../../../src/engine/platform/asset_file_android.cc ../../../src/engine/platform/asset_file_android.cc
../../../src/engine/platform/asset_file.cc ../../../src/engine/platform/asset_file.cc
../../../src/engine/platform/platform_android.cc ../../../src/engine/platform/platform_android.cc
../../../src/engine/platform/platform.cc
../../../src/engine/renderer/geometry.cc ../../../src/engine/renderer/geometry.cc
../../../src/engine/renderer/opengl/render_command.cc ../../../src/engine/renderer/opengl/render_command.cc
../../../src/engine/renderer/opengl/renderer_opengl_android.cc ../../../src/engine/renderer/opengl/renderer_opengl_android.cc

View File

@ -106,6 +106,7 @@ ENGINE_SRC := \
$(SRC_ROOT)/engine/persistent_data.cc \ $(SRC_ROOT)/engine/persistent_data.cc \
$(SRC_ROOT)/engine/platform/asset_file_linux.cc \ $(SRC_ROOT)/engine/platform/asset_file_linux.cc \
$(SRC_ROOT)/engine/platform/asset_file.cc \ $(SRC_ROOT)/engine/platform/asset_file.cc \
$(SRC_ROOT)/engine/platform/platform.cc \
$(SRC_ROOT)/engine/platform/platform_linux.cc \ $(SRC_ROOT)/engine/platform/platform_linux.cc \
$(SRC_ROOT)/engine/renderer/geometry.cc \ $(SRC_ROOT)/engine/renderer/geometry.cc \
$(SRC_ROOT)/engine/renderer/opengl/render_command.cc \ $(SRC_ROOT)/engine/renderer/opengl/render_command.cc \

View File

@ -95,7 +95,7 @@ void Credits::Show() {
void Credits::Hide() { void Credits::Hide() {
text_animator_.SetEndCallback(Animator::kBlending, [&]() -> void { text_animator_.SetEndCallback(Animator::kBlending, [&]() -> void {
for (int i = 0; i < kNumLines; ++i) for (int i = 0; i < kNumLines; ++i)
text_[i].Destroy(); text_[i].Destory();
text_animator_.SetEndCallback(Animator::kBlending, nullptr); text_animator_.SetEndCallback(Animator::kBlending, nullptr);
text_animator_.SetVisible(false); text_animator_.SetVisible(false);
}); });

View File

@ -1,7 +1,6 @@
#include "engine/engine.h" #include "engine/engine.h"
#include "base/log.h" #include "base/log.h"
#include "base/task_runner.h"
#include "engine/animator.h" #include "engine/animator.h"
#include "engine/audio/audio_mixer.h" #include "engine/audio/audio_mixer.h"
#include "engine/drawable.h" #include "engine/drawable.h"
@ -28,11 +27,6 @@ using namespace base;
namespace eng { namespace eng {
extern void KaliberMain(Platform* platform) {
TaskRunner::CreateThreadLocalTaskRunner();
Engine(platform).Run();
}
Engine* Engine::singleton = nullptr; Engine* Engine::singleton = nullptr;
Engine::Engine(Platform* platform) Engine::Engine(Platform* platform)
@ -73,41 +67,7 @@ Engine& Engine::Get() {
return *singleton; return *singleton;
} }
void Engine::Run() {
CHECK(Initialize()) << "Failed to initialize the engine.";
timer_.Reset();
float accumulator = 0.0;
float frame_frac = 0.0f;
for (;;) {
Draw(frame_frac);
// Accumulate time.
timer_.Update();
accumulator += timer_.GetSecondsPassed();
// Subdivide the frame time using fixed time steps.
while (accumulator >= time_step_) {
TaskRunner::GetThreadLocalTaskRunner()->SingleConsumerRun();
platform_->Update();
Update(time_step_);
if (platform_->should_exit()) {
return;
}
accumulator -= time_step_;
};
// Calculate frame fraction from remainder of the frame time.
frame_frac = accumulator / time_step_;
}
}
bool Engine::Initialize() { bool Engine::Initialize() {
thread_pool_.Initialize();
InitializeRenderer(); InitializeRenderer();
// Normalize viewport. // Normalize viewport.
@ -188,6 +148,20 @@ void Engine::Draw(float frame_frac) {
renderer_->Present(); renderer_->Present();
} }
void Engine::LostFocus() {
audio_mixer_->Suspend();
if (game_)
game_->LostFocus();
}
void Engine::GainedFocus(bool from_interstitial_ad) {
audio_mixer_->Resume();
if (game_)
game_->GainedFocus(from_interstitial_ad);
}
void Engine::AddDrawable(Drawable* drawable) { void Engine::AddDrawable(Drawable* drawable) {
DCHECK(std::find(drawables_.begin(), drawables_.end(), drawable) == DCHECK(std::find(drawables_.begin(), drawables_.end(), drawable) ==
drawables_.end()); drawables_.end());
@ -360,6 +334,40 @@ void Engine::RemoveCustomShader(const std::string& asset_name) {
shaders_.erase(it); shaders_.erase(it);
} }
void Engine::AddInputEvent(std::unique_ptr<InputEvent> event) {
if (replaying_)
return;
switch (event->GetType()) {
case InputEvent::kDragEnd:
if (((GetScreenSize() / 2) * 0.9f - event->GetVector()).Length() <=
0.25f) {
SetSatsVisible(!stats_->IsVisible());
// TODO: Enqueue DragCancel so we can consume this event.
}
break;
case InputEvent::kKeyPress:
if (event->GetKeyPress() == 's') {
SetSatsVisible(!stats_->IsVisible());
// Consume event.
return;
}
break;
case InputEvent::kDrag:
if (stats_->IsVisible()) {
if ((stats_->GetPosition() - event->GetVector()).Length() <=
stats_->GetSize().y)
stats_->SetPosition(event->GetVector());
// TODO: Enqueue DragCancel so we can consume this event.
}
break;
default:
break;
}
input_queue_.push_back(std::move(event));
}
std::unique_ptr<InputEvent> Engine::GetNextInputEvent() { std::unique_ptr<InputEvent> Engine::GetNextInputEvent() {
std::unique_ptr<InputEvent> event; std::unique_ptr<InputEvent> event;
@ -509,57 +517,6 @@ void Engine::OnWindowResized(int width, int height) {
} }
} }
void Engine::LostFocus() {
audio_mixer_->Suspend();
if (game_)
game_->LostFocus();
}
void Engine::GainedFocus(bool from_interstitial_ad) {
timer_.Reset();
audio_mixer_->Resume();
if (game_)
game_->GainedFocus(from_interstitial_ad);
}
void Engine::AddInputEvent(std::unique_ptr<InputEvent> event) {
if (replaying_)
return;
event->SetVector(ToPosition(event->GetVector()) * Vector2f(1, -1));
switch (event->GetType()) {
case InputEvent::kDragEnd:
if (((GetScreenSize() / 2) * 0.9f - event->GetVector()).Length() <=
0.25f) {
SetSatsVisible(!stats_->IsVisible());
// TODO: Enqueue DragCancel so we can consume this event.
}
break;
case InputEvent::kKeyPress:
if (event->GetKeyPress() == 's') {
SetSatsVisible(!stats_->IsVisible());
// Consume event.
return;
}
break;
case InputEvent::kDrag:
if (stats_->IsVisible()) {
if ((stats_->GetPosition() - event->GetVector()).Length() <=
stats_->GetSize().y)
stats_->SetPosition(event->GetVector());
// TODO: Enqueue DragCancel so we can consume this event.
}
break;
default:
break;
}
input_queue_.push_back(std::move(event));
}
void Engine::InitializeRenderer() { void Engine::InitializeRenderer() {
bool res; bool res;
#if defined(__ANDROID__) #if defined(__ANDROID__)
@ -650,7 +607,7 @@ void Engine::SetSatsVisible(bool visible) {
if (visible) if (visible)
stats_->Create("stats_tex"); stats_->Create("stats_tex");
else else
stats_->Destroy(); stats_->Destory();
} }
std::unique_ptr<Image> Engine::PrintStats() { std::unique_ptr<Image> Engine::PrintStats() {

View File

@ -8,8 +8,6 @@
#include <unordered_map> #include <unordered_map>
#include "base/random.h" #include "base/random.h"
#include "base/thread_pool.h"
#include "base/timer.h"
#include "base/vecmath.h" #include "base/vecmath.h"
#include "engine/persistent_data.h" #include "engine/persistent_data.h"
#include "engine/platform/platform_observer.h" #include "engine/platform/platform_observer.h"
@ -41,7 +39,13 @@ class Engine : public PlatformObserver {
static Engine& Get(); static Engine& Get();
void Run(); bool Initialize();
void Update(float delta_time);
void Draw(float frame_frac);
void LostFocus();
void GainedFocus(bool from_interstitial_ad);
void AddDrawable(Drawable* drawable); void AddDrawable(Drawable* drawable);
void RemoveDrawable(Drawable* drawable); void RemoveDrawable(Drawable* drawable);
@ -81,6 +85,7 @@ class Engine : public PlatformObserver {
Shader* GetCustomShader(const std::string& asset_name); Shader* GetCustomShader(const std::string& asset_name);
void RemoveCustomShader(const std::string& asset_name); void RemoveCustomShader(const std::string& asset_name);
void AddInputEvent(std::unique_ptr<InputEvent> event);
std::unique_ptr<InputEvent> GetNextInputEvent(); std::unique_ptr<InputEvent> GetNextInputEvent();
void StartRecording(const Json::Value& payload); void StartRecording(const Json::Value& payload);
@ -214,22 +219,12 @@ class Engine : public PlatformObserver {
bool replaying_ = false; bool replaying_ = false;
unsigned int replay_index_ = 0; unsigned int replay_index_ = 0;
base::ThreadPool thread_pool_;
base::Timer timer_;
base::Randomf random_; base::Randomf random_;
bool Initialize();
void Update(float delta_time);
void Draw(float frame_frac);
// PlatformObserver implementation // PlatformObserver implementation
void OnWindowCreated() final; void OnWindowCreated() final;
void OnWindowDestroyed() final; void OnWindowDestroyed() final;
void OnWindowResized(int width, int height) final; void OnWindowResized(int width, int height) final;
void LostFocus() final;
void GainedFocus(bool from_interstitial_ad) final;
void AddInputEvent(std::unique_ptr<InputEvent> event) final;
void InitializeRenderer(); void InitializeRenderer();

View File

@ -13,7 +13,7 @@ namespace eng {
ImageQuad::ImageQuad() = default; ImageQuad::ImageQuad() = default;
ImageQuad::~ImageQuad() { ImageQuad::~ImageQuad() {
Destroy(); Destory();
} }
void ImageQuad::Create(const std::string& asset_name, void ImageQuad::Create(const std::string& asset_name,
@ -33,7 +33,7 @@ void ImageQuad::Create(const std::string& asset_name,
} }
// TODO: typo // TODO: typo
void ImageQuad::Destroy() { void ImageQuad::Destory() {
if (texture_) { if (texture_) {
Engine::Get().ReleaseTexture(asset_name_); Engine::Get().ReleaseTexture(asset_name_);
texture_ = nullptr; texture_ = nullptr;

View File

@ -24,7 +24,7 @@ class ImageQuad final : public Animatable {
int frame_width = 0, int frame_width = 0,
int frame_height = 0); int frame_height = 0);
void Destroy(); void Destory();
void AutoScale(); void AutoScale();

View File

@ -27,8 +27,6 @@ class InputEvent {
InputEvent(Type type, char key) : type_(type), key_(key) {} InputEvent(Type type, char key) : type_(type), key_(key) {}
~InputEvent() = default; ~InputEvent() = default;
void SetVector(base::Vector2f vec) { vec_ = vec; }
Type GetType() const { return type_; } Type GetType() const { return type_; }
size_t GetPointerId() const { return pointer_id_; } size_t GetPointerId() const { return pointer_id_; }

View File

@ -0,0 +1,81 @@
#include "engine/platform/platform.h"
#include "base/log.h"
#include "base/task_runner.h"
#include "engine/engine.h"
using namespace base;
namespace eng {
Platform::Platform() = default;
Platform::~Platform() = default;
// Renderer* Platform::SwitchRenderer(bool vulkan) {
// DCHECK(renderer_);
// if ((dynamic_cast<RendererVulkan*>(renderer_.get()) && vulkan) ||
// (dynamic_cast<RendererOpenGL*>(renderer_.get()) && !vulkan))
// return renderer_.get();
// if (vulkan)
// renderer_ = std::make_unique<RendererVulkan>();
// else
// renderer_ = std::make_unique<RendererOpenGL>();
// bool result = InitializeRenderer();
// CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
// << " renderer.";
// LOG << "Switched to " << renderer_->GetDebugName() << " renderer.";
// return renderer_.get();
// }
void Platform::InitializeCommon() {
LOG << "Initializing platform.";
thread_pool_.Initialize();
TaskRunner::CreateThreadLocalTaskRunner();
}
void Platform::RunMainLoop() {
engine_ =
std::make_unique<Engine>(this);
bool res = engine_->Initialize();
CHECK(res) << "Failed to initialize the engine.";
// Use fixed time steps.
float time_step = engine_->time_step();
timer_.Reset();
float accumulator = 0.0;
float frame_frac = 0.0f;
for (;;) {
engine_->Draw(frame_frac);
// Accumulate time.
timer_.Update();
accumulator += timer_.GetSecondsPassed();
// Subdivide the frame time.
while (accumulator >= time_step) {
TaskRunner::GetThreadLocalTaskRunner()->SingleConsumerRun();
Update();
engine_->Update(time_step);
if (should_exit_) {
thread_pool_.Shutdown();
// engine_.reset();
return;
}
accumulator -= time_step;
};
// Calculate frame fraction from remainder of the frame time.
frame_frac = accumulator / time_step;
}
}
} // namespace eng

View File

@ -1,8 +1,12 @@
#ifndef ENGINE_PLATFORM_PLATFORM_H #ifndef ENGINE_PLATFORM_PLATFORM_H
#define ENGINE_PLATFORM_PLATFORM_H #define ENGINE_PLATFORM_PLATFORM_H
#include <memory>
#include <string> #include <string>
#include "base/thread_pool.h"
#include "base/timer.h"
#if defined(__ANDROID__) #if defined(__ANDROID__)
#include "../../base/vecmath.h" #include "../../base/vecmath.h"
@ -20,23 +24,30 @@ struct ANativeWindow;
namespace eng { namespace eng {
class Engine;
class PlatformObserver; class PlatformObserver;
class Platform { class Platform {
public: public:
#if defined(__ANDROID__)
Platform(android_app* app);
#elif defined(__linux__)
Platform(); Platform();
#endif
~Platform(); ~Platform();
#if defined(__ANDROID__)
void Initialize(android_app* app);
#elif defined(__linux__)
void Initialize();
#endif
void Shutdown();
void Update(); void Update();
void Exit(); void Exit();
void SetObserver(PlatformObserver* observer) { observer_ = observer; } void SetObserver(PlatformObserver* observer) { observer_ = observer; }
// Renderer* SwitchRenderer(bool vulkan);
void Vibrate(int duration); void Vibrate(int duration);
void ShowInterstitialAd(); void ShowInterstitialAd();
@ -45,6 +56,8 @@ class Platform {
void SetKeepScreenOn(bool keep_screen_on); void SetKeepScreenOn(bool keep_screen_on);
void RunMainLoop();
int GetDeviceDpi() const { return device_dpi_; } int GetDeviceDpi() const { return device_dpi_; }
const std::string& GetRootPath() const { return root_path_; } const std::string& GetRootPath() const { return root_path_; }
@ -55,8 +68,6 @@ class Platform {
bool mobile_device() const { return mobile_device_; } bool mobile_device() const { return mobile_device_; }
bool should_exit() const { return should_exit_; }
#if defined(__ANDROID__) #if defined(__ANDROID__)
ANativeWindow* GetWindow(); ANativeWindow* GetWindow();
#elif defined(__linux__) #elif defined(__linux__)
@ -64,7 +75,9 @@ class Platform {
Window GetWindow(); Window GetWindow();
#endif #endif
private: protected:
base::Timer timer_;
bool mobile_device_ = false; bool mobile_device_ = false;
int device_dpi_ = 100; int device_dpi_ = 100;
std::string root_path_; std::string root_path_;
@ -76,6 +89,10 @@ class Platform {
PlatformObserver* observer_ = nullptr; PlatformObserver* observer_ = nullptr;
std::unique_ptr<Engine> engine_;
base::ThreadPool thread_pool_;
#if defined(__ANDROID__) #if defined(__ANDROID__)
android_app* app_ = nullptr; android_app* app_ = nullptr;
@ -113,6 +130,8 @@ class Platform {
#endif #endif
void InitializeCommon();
Platform(const Platform&) = delete; Platform(const Platform&) = delete;
Platform& operator=(const Platform&) = delete; Platform& operator=(const Platform&) = delete;
}; };

View File

@ -1,13 +1,13 @@
#include "engine/platform/platform.h" #include "engine/platform/platform.h"
#include <memory>
#include <android_native_app_glue.h> #include <android_native_app_glue.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <jni.h> #include <jni.h>
#include <unistd.h> #include <unistd.h>
#include "base/log.h" #include "base/log.h"
#include "base/task_runner.h"
#include "engine/engine.h"
#include "engine/input_event.h" #include "engine/input_event.h"
#include "engine/platform/platform_observer.h" #include "engine/platform/platform_observer.h"
@ -201,12 +201,10 @@ int32_t GetDensityDpi(android_app* app) {
namespace eng { namespace eng {
void KaliberMain(Platform* platform);
int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { int32_t Platform::HandleInput(android_app* app, AInputEvent* event) {
Platform* platform = reinterpret_cast<Platform*>(app->userData); Platform* platform = reinterpret_cast<Platform*>(app->userData);
if (!platform->observer_) if (!platform->engine_)
return 0; return 0;
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY && if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY &&
@ -214,7 +212,7 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) {
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) { if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) {
auto input_event = auto input_event =
std::make_unique<InputEvent>(InputEvent::kNavigateBack); std::make_unique<InputEvent>(InputEvent::kNavigateBack);
platform->observer_->AddInputEvent(std::move(input_event)); platform->engine_->AddInputEvent(std::move(input_event));
} }
return 1; return 1;
} else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
@ -229,6 +227,7 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) {
int32_t id = AMotionEvent_getPointerId(event, i); int32_t id = AMotionEvent_getPointerId(event, i);
if (id < 2) { if (id < 2) {
pos[id] = {AMotionEvent_getX(event, i), AMotionEvent_getY(event, i)}; pos[id] = {AMotionEvent_getX(event, i), AMotionEvent_getY(event, i)};
pos[id] = platform->engine_->ToPosition(pos[id]);
} }
} }
@ -240,30 +239,34 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) {
switch (flags) { switch (flags) {
case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_DOWN:
case AMOTION_EVENT_ACTION_POINTER_DOWN: case AMOTION_EVENT_ACTION_POINTER_DOWN:
// DLOG << "AMOTION_EVENT_ACTION_DOWN - pointer_id: " << pointer_id;
platform->pointer_pos_[pointer_id] = pos[pointer_id]; platform->pointer_pos_[pointer_id] = pos[pointer_id];
platform->pointer_down_[pointer_id] = true; platform->pointer_down_[pointer_id] = true;
input_event = std::make_unique<InputEvent>(InputEvent::kDragStart, input_event =
pointer_id, pos[pointer_id]); std::make_unique<InputEvent>(InputEvent::kDragStart, pointer_id,
pos[pointer_id] * Vector2f(1, -1));
break; break;
case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_UP:
case AMOTION_EVENT_ACTION_POINTER_UP: case AMOTION_EVENT_ACTION_POINTER_UP:
// DLOG << "AMOTION_EVENT_ACTION_UP - pointer_id: " << pointer_id;
platform->pointer_pos_[pointer_id] = pos[pointer_id]; platform->pointer_pos_[pointer_id] = pos[pointer_id];
platform->pointer_down_[pointer_id] = false; platform->pointer_down_[pointer_id] = false;
input_event = std::make_unique<InputEvent>(InputEvent::kDragEnd, input_event =
pointer_id, pos[pointer_id]); std::make_unique<InputEvent>(InputEvent::kDragEnd, pointer_id,
pos[pointer_id] * Vector2f(1, -1));
break; break;
case AMOTION_EVENT_ACTION_MOVE: case AMOTION_EVENT_ACTION_MOVE:
if (platform->pointer_down_[0] && pos[0] != platform->pointer_pos_[0]) { if (platform->pointer_down_[0] && pos[0] != platform->pointer_pos_[0]) {
platform->pointer_pos_[0] = pos[0]; platform->pointer_pos_[0] = pos[0];
input_event = input_event = std::make_unique<InputEvent>(InputEvent::kDrag, 0,
std::make_unique<InputEvent>(InputEvent::kDrag, 0, pos[0]); pos[0] * Vector2f(1, -1));
} }
if (platform->pointer_down_[1] && pos[1] != platform->pointer_pos_[1]) { if (platform->pointer_down_[1] && pos[1] != platform->pointer_pos_[1]) {
platform->pointer_pos_[1] = pos[1]; platform->pointer_pos_[1] = pos[1];
input_event = input_event = std::make_unique<InputEvent>(InputEvent::kDrag, 1,
std::make_unique<InputEvent>(InputEvent::kDrag, 1, pos[1]); pos[1] * Vector2f(1, -1));
} }
break; break;
@ -273,7 +276,7 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) {
} }
if (input_event) { if (input_event) {
platform->observer_->AddInputEvent(std::move(input_event)); platform->engine_->AddInputEvent(std::move(input_event));
return 1; return 1;
} }
} }
@ -292,20 +295,18 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
DLOG << "APP_CMD_INIT_WINDOW"; DLOG << "APP_CMD_INIT_WINDOW";
if (app->window != NULL) { if (app->window != NULL) {
platform->SetFrameRate(60); platform->SetFrameRate(60);
if (platform->observer_)
platform->observer_->OnWindowCreated(); platform->observer_->OnWindowCreated();
} }
break; break;
case APP_CMD_TERM_WINDOW: case APP_CMD_TERM_WINDOW:
DLOG << "APP_CMD_TERM_WINDOW"; DLOG << "APP_CMD_TERM_WINDOW";
if (platform->observer_)
platform->observer_->OnWindowDestroyed(); platform->observer_->OnWindowDestroyed();
break; break;
case APP_CMD_CONFIG_CHANGED: case APP_CMD_CONFIG_CHANGED:
DLOG << "APP_CMD_CONFIG_CHANGED"; DLOG << "APP_CMD_CONFIG_CHANGED";
if (platform->app_->window != NULL && platform->observer_) if (platform->app_->window != NULL)
platform->observer_->OnWindowResized( platform->observer_->OnWindowResized(
ANativeWindow_getWidth(app->window), ANativeWindow_getWidth(app->window),
ANativeWindow_getHeight(app->window)); ANativeWindow_getHeight(app->window));
@ -317,18 +318,18 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
case APP_CMD_GAINED_FOCUS: case APP_CMD_GAINED_FOCUS:
DLOG << "APP_CMD_GAINED_FOCUS"; DLOG << "APP_CMD_GAINED_FOCUS";
// platform->timer_.Reset(); platform->timer_.Reset();
platform->has_focus_ = true; platform->has_focus_ = true;
if (platform->observer_) if (platform->engine_)
platform->observer_->GainedFocus(g_showing_interstitial_ad); platform->engine_->GainedFocus(g_showing_interstitial_ad);
g_showing_interstitial_ad = false; g_showing_interstitial_ad = false;
break; break;
case APP_CMD_LOST_FOCUS: case APP_CMD_LOST_FOCUS:
DLOG << "APP_CMD_LOST_FOCUS"; DLOG << "APP_CMD_LOST_FOCUS";
platform->has_focus_ = false; platform->has_focus_ = false;
if (platform->observer_) if (platform->engine_)
platform->observer_->LostFocus(); platform->engine_->LostFocus();
break; break;
case APP_CMD_LOW_MEMORY: case APP_CMD_LOW_MEMORY:
@ -337,8 +338,11 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
} }
} }
Platform::Platform(android_app* app) { void Platform::Initialize(android_app* app) {
Platform::InitializeCommon();
app_ = app; app_ = app;
mobile_device_ = true; mobile_device_ = true;
root_path_ = ::GetApkPath(app->activity); root_path_ = ::GetApkPath(app->activity);
@ -372,7 +376,7 @@ Platform::Platform(android_app* app) {
Update(); Update();
} }
Platform::~Platform() { void Platform::Shutdown() {
LOG << "Shutting down platform."; LOG << "Shutting down platform.";
} }
@ -433,7 +437,9 @@ ANativeWindow* Platform::GetWindow() {
} // namespace eng } // namespace eng
void android_main(android_app* app) { void android_main(android_app* app) {
eng::Platform platform(app); eng::Platform platform;
KaliberMain(&platform); platform.Initialize(app);
platform.RunMainLoop();
platform.Shutdown();
_exit(0); _exit(0);
} }

View File

@ -1,19 +1,18 @@
#include "engine/platform/platform.h" #include "engine/platform/platform.h"
#include <memory>
#include "base/log.h" #include "base/log.h"
#include "base/task_runner.h"
#include "base/vecmath.h" #include "base/vecmath.h"
#include "engine/engine.h"
#include "engine/input_event.h" #include "engine/input_event.h"
#include "engine/platform/platform_observer.h"
using namespace base; using namespace base;
namespace eng { namespace eng {
void KaliberMain(Platform* platform); void Platform::Initialize() {
Platform::InitializeCommon();
Platform::Platform() {
root_path_ = "../../"; root_path_ = "../../";
LOG << "Root path: " << root_path_.c_str(); LOG << "Root path: " << root_path_.c_str();
@ -33,7 +32,7 @@ Platform::Platform() {
XSetWMProtocols(display_, window_, &WM_DELETE_WINDOW, 1); XSetWMProtocols(display_, window_, &WM_DELETE_WINDOW, 1);
} }
Platform::~Platform() { void Platform::Shutdown() {
LOG << "Shutting down platform."; LOG << "Shutting down platform.";
DestroyWindow(); DestroyWindow();
} }
@ -47,41 +46,47 @@ void Platform::Update() {
KeySym key = XLookupKeysym(&e.xkey, 0); KeySym key = XLookupKeysym(&e.xkey, 0);
auto input_event = auto input_event =
std::make_unique<InputEvent>(InputEvent::kKeyPress, (char)key); std::make_unique<InputEvent>(InputEvent::kKeyPress, (char)key);
observer_->AddInputEvent(std::move(input_event)); engine_->AddInputEvent(std::move(input_event));
// TODO: e.xkey.state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)) // TODO: e.xkey.state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask))
break; break;
} }
case MotionNotify: { case MotionNotify: {
Vector2f v(e.xmotion.x, e.xmotion.y); Vector2f v(e.xmotion.x, e.xmotion.y);
auto input_event = v = engine_->ToPosition(v);
std::make_unique<InputEvent>(InputEvent::kDrag, 0, v); // DLOG << "drag: " << v;
observer_->AddInputEvent(std::move(input_event)); auto input_event = std::make_unique<InputEvent>(InputEvent::kDrag, 0,
v * Vector2f(1, -1));
engine_->AddInputEvent(std::move(input_event));
break; break;
} }
case ButtonPress: { case ButtonPress: {
if (e.xbutton.button == 1) { if (e.xbutton.button == 1) {
Vector2f v(e.xbutton.x, e.xbutton.y); Vector2f v(e.xbutton.x, e.xbutton.y);
auto input_event = v = engine_->ToPosition(v);
std::make_unique<InputEvent>(InputEvent::kDragStart, 0, v); // DLOG << "drag-start: " << v;
observer_->AddInputEvent(std::move(input_event)); auto input_event = std::make_unique<InputEvent>(
InputEvent::kDragStart, 0, v * Vector2f(1, -1));
engine_->AddInputEvent(std::move(input_event));
} }
break; break;
} }
case ButtonRelease: { case ButtonRelease: {
if (e.xbutton.button == 1) { if (e.xbutton.button == 1) {
Vector2f v(e.xbutton.x, e.xbutton.y); Vector2f v(e.xbutton.x, e.xbutton.y);
auto input_event = v = engine_->ToPosition(v);
std::make_unique<InputEvent>(InputEvent::kDragEnd, 0, v); // DLOG << "drag-end!";
observer_->AddInputEvent(std::move(input_event)); auto input_event = std::make_unique<InputEvent>(
InputEvent::kDragEnd, 0, v * Vector2f(1, -1));
engine_->AddInputEvent(std::move(input_event));
} }
break; break;
} }
case FocusOut: { case FocusOut: {
observer_->LostFocus(); engine_->LostFocus();
break; break;
} }
case FocusIn: { case FocusIn: {
observer_->GainedFocus(false); engine_->GainedFocus(false);
break; break;
} }
case ClientMessage: { case ClientMessage: {
@ -169,6 +174,8 @@ XVisualInfo* Platform::GetXVisualInfo(Display* display) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
eng::Platform platform; eng::Platform platform;
KaliberMain(&platform); platform.Initialize();
platform.RunMainLoop();
platform.Shutdown();
return 0; return 0;
} }

View File

@ -3,8 +3,6 @@
namespace eng { namespace eng {
class InputEvent;
class PlatformObserver { class PlatformObserver {
public: public:
PlatformObserver() = default; PlatformObserver() = default;
@ -13,9 +11,6 @@ class PlatformObserver {
virtual void OnWindowCreated() = 0; virtual void OnWindowCreated() = 0;
virtual void OnWindowDestroyed() = 0; virtual void OnWindowDestroyed() = 0;
virtual void OnWindowResized(int width, int height) = 0; virtual void OnWindowResized(int width, int height) = 0;
virtual void LostFocus() = 0;
virtual void GainedFocus(bool from_interstitial_ad) = 0;
virtual void AddInputEvent(std::unique_ptr<InputEvent> event) = 0;
}; };
} // namespace eng } // namespace eng

View File

@ -89,6 +89,10 @@ class RendererOpenGL final : public Renderer {
const char* GetDebugName() final { return "OpenGL"; } const char* GetDebugName() final { return "OpenGL"; }
// #if defined(__linux__) && !defined(__ANDROID__)
// XVisualInfo* GetXVisualInfo(Display* display) final;
// #endif
private: private:
struct GeometryOpenGL { struct GeometryOpenGL {
struct Element { struct Element {

View File

@ -61,4 +61,11 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) {
} }
} }
// XVisualInfo* RendererOpenGL::GetXVisualInfo(Display* display) {
// // Look for the right visual to set up the OpenGL context.
// GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER,
// None};
// return glXChooseVisual(display, 0, glx_attributes);
// }
} // namespace eng } // namespace eng

View File

@ -94,6 +94,10 @@ class Renderer {
virtual const char* GetDebugName() = 0; virtual const char* GetDebugName() = 0;
// #if defined(__linux__) && !defined(__ANDROID__)
// virtual XVisualInfo* GetXVisualInfo(Display* display) = 0;
// #endif
protected: protected:
struct TextureCompression { struct TextureCompression {
unsigned etc1 : 1; unsigned etc1 : 1;

View File

@ -74,6 +74,10 @@ class RendererVulkan final : public Renderer {
const char* GetDebugName() final { return "Vulkan"; } const char* GetDebugName() final { return "Vulkan"; }
// #if defined(__linux__) && !defined(__ANDROID__)
// XVisualInfo* GetXVisualInfo(Display* display) final;
// #endif
private: private:
// VkBuffer or VkImage with allocator. // VkBuffer or VkImage with allocator.
template <typename T> template <typename T>

View File

@ -24,4 +24,13 @@ bool RendererVulkan::Initialize(Display* display, Window window) {
return InitializeInternal(); return InitializeInternal();
} }
// XVisualInfo* RendererVulkan::GetXVisualInfo(Display* display) {
// long visual_mask = VisualScreenMask;
// int num_visuals;
// XVisualInfo visual_info_template = {};
// visual_info_template.screen = DefaultScreen(display);
// return XGetVisualInfo(display, visual_mask, &visual_info_template,
// &num_visuals);
// }
} // namespace eng } // namespace eng