Compare commits

...

4 Commits

Author SHA1 Message Date
Attila Uygun 2f0a2f52eb log 2023-05-26 14:49:53 +02:00
Attila Uygun 231efe1c92 Renderer(base::Closure context_lost_cb) 2023-05-26 14:23:36 +02:00
Attila Uygun 98e7e5f107 Initialize(Platform* platform) 2023-05-26 13:50:29 +02:00
Attila Uygun a00110cc94 CreateRenderer 2023-05-26 13:19:53 +02:00
13 changed files with 100 additions and 145 deletions

View File

@ -37,20 +37,14 @@ Engine* Engine::singleton = nullptr;
Engine::Engine(Platform* platform) Engine::Engine(Platform* platform)
: platform_(platform), : platform_(platform),
#if (USE_VULKAN_RENDERER == 1)
renderer_{std::make_unique<RendererVulkan>()},
#else
renderer_{std::make_unique<RendererOpenGL>()},
#endif
audio_mixer_{std::make_unique<AudioMixer>()}, audio_mixer_{std::make_unique<AudioMixer>()},
quad_{CreateRenderResource<Geometry>()}, quad_{std::make_unique<Geometry>(nullptr)},
pass_through_shader_{CreateRenderResource<Shader>()}, pass_through_shader_{std::make_unique<Shader>(nullptr)},
solid_shader_{CreateRenderResource<Shader>()} { solid_shader_{std::make_unique<Shader>(nullptr)} {
DCHECK(!singleton); DCHECK(!singleton);
singleton = this; singleton = this;
platform_->SetObserver(this); platform_->SetObserver(this);
renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this));
stats_ = std::make_unique<ImageQuad>(); stats_ = std::make_unique<ImageQuad>();
} }
@ -74,7 +68,7 @@ Engine& Engine::Get() {
} }
void Engine::Run() { void Engine::Run() {
CHECK(Initialize()) << "Failed to initialize the engine."; Initialize();
timer_.Reset(); timer_.Reset();
float accumulator = 0.0; float accumulator = 0.0;
@ -90,14 +84,12 @@ void Engine::Run() {
// Subdivide the frame time using fixed time steps. // Subdivide the frame time using fixed time steps.
while (accumulator >= time_step_) { while (accumulator >= time_step_) {
TaskRunner::GetThreadLocalTaskRunner()->SingleConsumerRun(); TaskRunner::GetThreadLocalTaskRunner()->SingleConsumerRun();
platform_->Update(); platform_->Update();
Update(time_step_); Update(time_step_);
if (platform_->should_exit()) {
return;
}
accumulator -= time_step_; accumulator -= time_step_;
if (platform_->should_exit())
return;
}; };
// Calculate frame fraction from remainder of the frame time. // Calculate frame fraction from remainder of the frame time.
@ -105,10 +97,12 @@ void Engine::Run() {
} }
} }
bool Engine::Initialize() { void Engine::Initialize() {
LOG << "Initializing engine.";
thread_pool_.Initialize(); thread_pool_.Initialize();
InitializeRenderer(); CreateRenderer(true);
// Normalize viewport. // Normalize viewport.
if (GetScreenWidth() > GetScreenHeight()) { if (GetScreenWidth() > GetScreenHeight()) {
@ -125,29 +119,16 @@ bool Engine::Initialize() {
LOG << "image scale factor: " << GetImageScaleFactor(); LOG << "image scale factor: " << GetImageScaleFactor();
CreateTextureCompressors();
system_font_ = std::make_unique<Font>(); system_font_ = std::make_unique<Font>();
system_font_->Load("engine/RobotoMono-Regular.ttf"); system_font_->Load("engine/RobotoMono-Regular.ttf");
if (!CreateRenderResources())
return false;
SetImageSource("stats_tex", std::bind(&Engine::PrintStats, this)); SetImageSource("stats_tex", std::bind(&Engine::PrintStats, this));
stats_->SetZOrder(std::numeric_limits<int>::max()); stats_->SetZOrder(std::numeric_limits<int>::max());
game_ = GameFactoryBase::CreateGame(""); game_ = GameFactoryBase::CreateGame("");
if (!game_) { CHECK(game_) << "No game found to run.";
LOG << "No game found to run.";
return false;
}
if (!game_->Initialize()) { CHECK(game_->Initialize()) << "Failed to initialize the game.";
LOG << "Failed to initialize the game.";
return false;
}
return true;
} }
void Engine::Update(float delta_time) { void Engine::Update(float delta_time) {
@ -216,26 +197,30 @@ void Engine::RemoveAnimator(Animator* animator) {
} }
} }
void Engine::SwitchRenderer(bool vulkan) { void Engine::CreateRenderer(bool vulkan) {
// Renderer* new_renderer = platform_->SwitchRenderer(vulkan); if ((dynamic_cast<RendererVulkan*>(renderer_.get()) && vulkan) ||
// if (new_renderer == renderer_) (dynamic_cast<RendererOpenGL*>(renderer_.get()) && !vulkan))
// return; return;
// renderer_ = new_renderer; if (vulkan)
// renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this)); renderer_ =
// CreateTextureCompressors(); std::make_unique<RendererVulkan>(std::bind(&Engine::ContextLost, this));
else
renderer_ =
std::make_unique<RendererOpenGL>(std::bind(&Engine::ContextLost, this));
// for (auto& t : textures_) bool result = renderer_->Initialize(platform_);
// t.second.texture->SetRenderer(renderer_); if (!result && vulkan) {
LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer.";
LOG << "Fallback to OpenGL renderer.";
CreateRenderer(false);
return;
}
CHECK(result) << "Failed to initialize " << renderer_->GetDebugName()
<< " renderer.";
// for (auto& s : shaders_) CreateTextureCompressors();
// s.second.shader->SetRenderer(renderer_); ContextLost();
// quad_->SetRenderer(renderer_);
// pass_through_shader_->SetRenderer(renderer_);
// solid_shader_->SetRenderer(renderer_);
// ContextLost();
} }
void Engine::Exit() { void Engine::Exit() {
@ -494,7 +479,7 @@ bool Engine::IsMobile() const {
} }
void Engine::OnWindowCreated() { void Engine::OnWindowCreated() {
InitializeRenderer(); renderer_->Initialize(platform_);
} }
void Engine::OnWindowDestroyed() { void Engine::OnWindowDestroyed() {
@ -505,7 +490,7 @@ void Engine::OnWindowResized(int width, int height) {
if (width != renderer_->screen_width() || if (width != renderer_->screen_width() ||
height != renderer_->screen_height()) { height != renderer_->screen_height()) {
renderer_->Shutdown(); renderer_->Shutdown();
InitializeRenderer(); renderer_->Initialize(platform_);
} }
} }
@ -560,17 +545,6 @@ void Engine::AddInputEvent(std::unique_ptr<InputEvent> event) {
input_queue_.push_back(std::move(event)); input_queue_.push_back(std::move(event));
} }
void Engine::InitializeRenderer() {
bool res;
#if defined(__ANDROID__)
res = renderer_->Initialize(platform_->GetWindow());
#elif defined(__linux__)
res = renderer_->Initialize(platform_->GetDisplay(), platform_->GetWindow());
#endif
CHECK(res) << "Failed to initialize " << renderer_->GetDebugName()
<< " renderer.";
}
void Engine::CreateTextureCompressors() { void Engine::CreateTextureCompressors() {
tex_comp_alpha_.reset(); tex_comp_alpha_.reset();
tex_comp_opaque_.reset(); tex_comp_opaque_.reset();
@ -594,24 +568,10 @@ void Engine::CreateTextureCompressors() {
} }
void Engine::ContextLost() { void Engine::ContextLost() {
CreateRenderResources(); quad_->SetRenderer(renderer_.get());
pass_through_shader_->SetRenderer(renderer_.get());
solid_shader_->SetRenderer(renderer_.get());
for (auto& t : textures_) {
t.second.texture->Destroy();
RefreshImage(t.first);
}
for (auto& s : shaders_) {
auto source = std::make_unique<ShaderSource>();
if (source->Load(s.second.file_name))
s.second.shader->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
}
game_->ContextLost();
}
bool Engine::CreateRenderResources() {
// This creates a normalized unit sized quad. // This creates a normalized unit sized quad.
static const char vertex_description[] = "p2f;t2f"; static const char vertex_description[] = "p2f;t2f";
static const float vertices[] = { static const float vertices[] = {
@ -626,23 +586,37 @@ bool Engine::CreateRenderResources() {
// Create the shader we can reuse for texture rendering. // Create the shader we can reuse for texture rendering.
auto source = std::make_unique<ShaderSource>(); auto source = std::make_unique<ShaderSource>();
if (!source->Load("engine/pass_through.glsl")) { if (source->Load("engine/pass_through.glsl")) {
pass_through_shader_->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
} else {
LOG << "Could not create pass through shader."; LOG << "Could not create pass through shader.";
return false;
} }
pass_through_shader_->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
// Create the shader we can reuse for solid rendering. // Create the shader we can reuse for solid rendering.
source = std::make_unique<ShaderSource>(); source = std::make_unique<ShaderSource>();
if (!source->Load("engine/solid.glsl")) { if (source->Load("engine/solid.glsl")) {
solid_shader_->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
} else {
LOG << "Could not create solid shader."; LOG << "Could not create solid shader.";
return false;
} }
solid_shader_->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
return true; for (auto& t : textures_) {
t.second.texture->SetRenderer(renderer_.get());
RefreshImage(t.first);
}
for (auto& s : shaders_) {
s.second.shader->SetRenderer(renderer_.get());
auto source = std::make_unique<ShaderSource>();
if (source->Load(s.second.file_name))
s.second.shader->Create(std::move(source), quad_->vertex_description(),
quad_->primitive(), false);
}
if (game_)
game_->ContextLost();
} }
void Engine::SetSatsVisible(bool visible) { void Engine::SetSatsVisible(bool visible) {

View File

@ -49,7 +49,7 @@ class Engine : public PlatformObserver {
void AddAnimator(Animator* animator); void AddAnimator(Animator* animator);
void RemoveAnimator(Animator* animator); void RemoveAnimator(Animator* animator);
void SwitchRenderer(bool vulkan); void CreateRenderer(bool vulkan);
void Exit(); void Exit();
@ -218,7 +218,7 @@ class Engine : public PlatformObserver {
base::Timer timer_; base::Timer timer_;
base::Randomf random_; base::Randomf random_;
bool Initialize(); void Initialize();
void Update(float delta_time); void Update(float delta_time);
void Draw(float frame_frac); void Draw(float frame_frac);
@ -231,14 +231,10 @@ 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 InitializeRenderer();
void CreateTextureCompressors(); void CreateTextureCompressors();
void ContextLost(); void ContextLost();
bool CreateRenderResources();
void SetSatsVisible(bool visible); void SetSatsVisible(bool visible);
std::unique_ptr<Image> PrintStats(); std::unique_ptr<Image> PrintStats();

View File

@ -338,6 +338,8 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
} }
Platform::Platform(android_app* app) { Platform::Platform(android_app* app) {
LOG << "Initializing platform.";
app_ = app; app_ = app;
mobile_device_ = true; mobile_device_ = true;

View File

@ -14,6 +14,8 @@ namespace eng {
void KaliberMain(Platform* platform); void KaliberMain(Platform* platform);
Platform::Platform() { Platform::Platform() {
LOG << "Initializing platform.";
root_path_ = "../../"; root_path_ = "../../";
LOG << "Root path: " << root_path_.c_str(); LOG << "Root path: " << root_path_.c_str();

View File

@ -40,8 +40,9 @@ const std::string kAttributeNames[eng::kAttribType_Max] = {
namespace eng { namespace eng {
#ifdef THREADED_RENDERING #ifdef THREADED_RENDERING
RendererOpenGL::RendererOpenGL() RendererOpenGL::RendererOpenGL(base::Closure context_lost_cb)
: main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()) {} : Renderer(context_lost_cb),
main_thread_task_runner_(TaskRunner::GetThreadLocalTaskRunner()) {}
#else #else
RendererOpenGL::RendererOpenGL() = default; RendererOpenGL::RendererOpenGL() = default;
#endif // THREADED_RENDERING #endif // THREADED_RENDERING

View File

@ -37,15 +37,10 @@ struct RenderCommand;
class RendererOpenGL final : public Renderer { class RendererOpenGL final : public Renderer {
public: public:
RendererOpenGL(); RendererOpenGL(base::Closure context_lost_cb);
~RendererOpenGL() final; ~RendererOpenGL() final;
#if defined(__ANDROID__) virtual bool Initialize(Platform* platform) final;
bool Initialize(ANativeWindow* window) final;
#elif defined(__linux__)
bool Initialize(Display* display, Window window) final;
#endif
void Shutdown() final; void Shutdown() final;
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final; uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;

View File

@ -3,14 +3,15 @@
#include <android/native_window.h> #include <android/native_window.h>
#include "base/log.h" #include "base/log.h"
#include "engine/platform/platform.h"
#include "third_party/android/GLContext.h" #include "third_party/android/GLContext.h"
namespace eng { namespace eng {
bool RendererOpenGL::Initialize(ANativeWindow* window) { bool RendererOpenGL::Initialize(Platform* platform) {
LOG << "Initializing renderer."; LOG << "Initializing renderer.";
window_ = window; window_ = platform->GetWindow();
return StartRenderThread(); return StartRenderThread();
} }

View File

@ -1,14 +1,15 @@
#include "engine/renderer/opengl/renderer_opengl.h" #include "engine/renderer/opengl/renderer_opengl.h"
#include "base/log.h" #include "base/log.h"
#include "engine/platform/platform.h"
namespace eng { namespace eng {
bool RendererOpenGL::Initialize(Display* display, Window window) { bool RendererOpenGL::Initialize(Platform* platform) {
LOG << "Initializing renderer."; LOG << "Initializing renderer.";
display_ = display; display_ = platform->GetDisplay();
window_ = window; window_ = platform->GetWindow();
XWindowAttributes xwa; XWindowAttributes xwa;
XGetWindowAttributes(display_, window_, &xwa); XGetWindowAttributes(display_, window_, &xwa);
@ -24,8 +25,7 @@ bool RendererOpenGL::InitInternal() {
GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER,
None}; None};
XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes); XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes);
glx_context_ = glx_context_ = glXCreateContext(display_, visual_info, NULL, GL_TRUE);
glXCreateContext(display_, visual_info, NULL, GL_TRUE);
if (!glx_context_) { if (!glx_context_) {
LOG << "Couldn't create the glx context."; LOG << "Couldn't create the glx context.";
return false; return false;

View File

@ -4,40 +4,26 @@
#include <memory> #include <memory>
#include <string> #include <string>
#if defined(__linux__) && !defined(__ANDROID__)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#endif
#include "base/closure.h" #include "base/closure.h"
#include "base/vecmath.h" #include "base/vecmath.h"
#include "engine/renderer/renderer_types.h" #include "engine/renderer/renderer_types.h"
#if defined(__ANDROID__)
struct ANativeWindow;
#endif
namespace eng { namespace eng {
class Image; class Image;
class ShaderSource; class ShaderSource;
class Mesh; class Mesh;
class Platform;
class Renderer { class Renderer {
public: public:
const unsigned kInvalidId = 0; const unsigned kInvalidId = 0;
Renderer() = default; Renderer(base::Closure context_lost_cb)
: context_lost_cb_{std::move(context_lost_cb)} {}
virtual ~Renderer() = default; virtual ~Renderer() = default;
void SetContextLostCB(base::Closure cb) { context_lost_cb_ = std::move(cb); } virtual bool Initialize(Platform* platform) = 0;
#if defined(__ANDROID__)
virtual bool Initialize(ANativeWindow* window) = 0;
#elif defined(__linux__)
virtual bool Initialize(Display* display, Window window) = 0;
#endif
virtual void Shutdown() = 0; virtual void Shutdown() = 0;
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0; virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;

View File

@ -370,7 +370,8 @@ std::pair<int, int> GetNumBlocksForImageFormat(VkFormat format,
namespace eng { namespace eng {
RendererVulkan::RendererVulkan() = default; RendererVulkan::RendererVulkan(base::Closure context_lost_cb)
: Renderer(context_lost_cb) {}
RendererVulkan::~RendererVulkan() { RendererVulkan::~RendererVulkan() {
Shutdown(); Shutdown();

View File

@ -18,19 +18,12 @@
namespace eng { namespace eng {
class Image;
class RendererVulkan final : public Renderer { class RendererVulkan final : public Renderer {
public: public:
RendererVulkan(); RendererVulkan(base::Closure context_lost_cb);
~RendererVulkan() final; ~RendererVulkan() final;
#if defined(__ANDROID__) virtual bool Initialize(Platform* platform) final;
bool Initialize(ANativeWindow* window) final;
#elif defined(__linux__)
bool Initialize(Display* display, Window window) final;
#endif
void Shutdown() final; void Shutdown() final;
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final; uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;

View File

@ -3,20 +3,22 @@
#include <android/native_window.h> #include <android/native_window.h>
#include "base/log.h" #include "base/log.h"
#include "engine/platform/platform.h"
namespace eng { namespace eng {
bool RendererVulkan::Initialize(ANativeWindow* window) { bool RendererVulkan::Initialize(Platform* platform) {
LOG << "Initializing renderer."; LOG << "Initializing renderer.";
screen_width_ = ANativeWindow_getWidth(window); screen_width_ = ANativeWindow_getWidth(platform->GetWindow());
screen_height_ = ANativeWindow_getHeight(window); screen_height_ = ANativeWindow_getHeight(platform->GetWindow());
if (!context_.Initialize()) { if (!context_.Initialize()) {
LOG << "Failed to initialize Vulkan context."; LOG << "Failed to initialize Vulkan context.";
return false; return false;
} }
if (!context_.CreateWindow(window, screen_width_, screen_height_)) { if (!context_.CreateWindow(platform->GetWindow(), screen_width_,
screen_height_)) {
LOG << "Vulkan context failed to create window."; LOG << "Vulkan context failed to create window.";
return false; return false;
} }

View File

@ -1,14 +1,15 @@
#include "engine/renderer/vulkan/renderer_vulkan.h" #include "engine/renderer/vulkan/renderer_vulkan.h"
#include "base/log.h" #include "base/log.h"
#include "engine/platform/platform.h"
namespace eng { namespace eng {
bool RendererVulkan::Initialize(Display* display, Window window) { bool RendererVulkan::Initialize(Platform* platform) {
LOG << "Initializing renderer."; LOG << "Initializing renderer.";
XWindowAttributes xwa; XWindowAttributes xwa;
XGetWindowAttributes(display, window, &xwa); XGetWindowAttributes(platform->GetDisplay(), platform->GetWindow(), &xwa);
screen_width_ = xwa.width; screen_width_ = xwa.width;
screen_height_ = xwa.height; screen_height_ = xwa.height;
@ -16,7 +17,8 @@ bool RendererVulkan::Initialize(Display* display, Window window) {
LOG << "Failed to initialize Vulkan context."; LOG << "Failed to initialize Vulkan context.";
return false; return false;
} }
if (!context_.CreateWindow(display, window, screen_width_, screen_height_)) { if (!context_.CreateWindow(platform->GetDisplay(), platform->GetWindow(),
screen_width_, screen_height_)) {
LOG << "Vulkan context failed to create window."; LOG << "Vulkan context failed to create window.";
return false; return false;
} }