mirror of https://github.com/auygun/kaliber.git
Support for switching between renderers in run-time
This commit is contained in:
parent
b7f1f7faa2
commit
b160ae0bd3
|
@ -71,22 +71,7 @@ bool Engine::Initialize() {
|
|||
|
||||
LOG << "image scale factor: " << GetImageScaleFactor();
|
||||
|
||||
if (renderer_->SupportsDXT5()) {
|
||||
tex_comp_alpha_ = TextureCompressor::Create(TextureCompressor::kFormatDXT5);
|
||||
} else if (renderer_->SupportsATC()) {
|
||||
tex_comp_alpha_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatATCIA);
|
||||
}
|
||||
|
||||
if (renderer_->SupportsDXT1()) {
|
||||
tex_comp_opaque_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatDXT1);
|
||||
} else if (renderer_->SupportsATC()) {
|
||||
tex_comp_opaque_ = TextureCompressor::Create(TextureCompressor::kFormatATC);
|
||||
} else if (renderer_->SupportsETC1()) {
|
||||
tex_comp_opaque_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatETC1);
|
||||
}
|
||||
CreateTextureCompressors();
|
||||
|
||||
system_font_ = std::make_unique<Font>();
|
||||
system_font_->Load("engine/RobotoMono-Regular.ttf");
|
||||
|
@ -199,6 +184,28 @@ void Engine::RemoveAnimator(Animator* animator) {
|
|||
}
|
||||
}
|
||||
|
||||
void Engine::SwitchRenderer(bool vulkan) {
|
||||
Renderer* new_renderer = platform_->SwitchRenderer(vulkan);
|
||||
if (new_renderer == renderer_)
|
||||
return;
|
||||
|
||||
renderer_ = new_renderer;
|
||||
renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this));
|
||||
CreateTextureCompressors();
|
||||
|
||||
for (auto& t : textures_)
|
||||
t.second.texture->SetRenderer(renderer_);
|
||||
|
||||
for (auto& s : shaders_)
|
||||
s.second.shader->SetRenderer(renderer_);
|
||||
|
||||
quad_->SetRenderer(renderer_);
|
||||
pass_through_shader_->SetRenderer(renderer_);
|
||||
solid_shader_->SetRenderer(renderer_);
|
||||
|
||||
ContextLost();
|
||||
}
|
||||
|
||||
void Engine::Exit() {
|
||||
platform_->Exit();
|
||||
}
|
||||
|
@ -488,6 +495,28 @@ bool Engine::IsMobile() const {
|
|||
return platform_->mobile_device();
|
||||
}
|
||||
|
||||
void Engine::CreateTextureCompressors() {
|
||||
tex_comp_alpha_.reset();
|
||||
tex_comp_opaque_.reset();
|
||||
|
||||
if (renderer_->SupportsDXT5()) {
|
||||
tex_comp_alpha_ = TextureCompressor::Create(TextureCompressor::kFormatDXT5);
|
||||
} else if (renderer_->SupportsATC()) {
|
||||
tex_comp_alpha_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatATCIA);
|
||||
}
|
||||
|
||||
if (renderer_->SupportsDXT1()) {
|
||||
tex_comp_opaque_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatDXT1);
|
||||
} else if (renderer_->SupportsATC()) {
|
||||
tex_comp_opaque_ = TextureCompressor::Create(TextureCompressor::kFormatATC);
|
||||
} else if (renderer_->SupportsETC1()) {
|
||||
tex_comp_opaque_ =
|
||||
TextureCompressor::Create(TextureCompressor::kFormatETC1);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::ContextLost() {
|
||||
CreateRenderResources();
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ class Engine {
|
|||
void AddAnimator(Animator* animator);
|
||||
void RemoveAnimator(Animator* animator);
|
||||
|
||||
void SwitchRenderer(bool vulkan);
|
||||
|
||||
void Exit();
|
||||
|
||||
// Convert size from pixels to viewport scale.
|
||||
|
@ -222,6 +224,8 @@ class Engine {
|
|||
|
||||
base::Randomf random_;
|
||||
|
||||
void CreateTextureCompressors();
|
||||
|
||||
void ContextLost();
|
||||
|
||||
bool CreateRenderResources();
|
||||
|
|
|
@ -22,6 +22,25 @@ 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.";
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@ class Platform {
|
|||
|
||||
void Exit();
|
||||
|
||||
Renderer* SwitchRenderer(bool vulkan);
|
||||
|
||||
void Vibrate(int duration);
|
||||
|
||||
void ShowInterstitialAd();
|
||||
|
@ -121,6 +123,8 @@ class Platform {
|
|||
void InitializeCommon();
|
||||
void ShutdownCommon();
|
||||
|
||||
bool InitializeRenderer();
|
||||
|
||||
Platform(const Platform&) = delete;
|
||||
Platform& operator=(const Platform&) = delete;
|
||||
};
|
||||
|
|
|
@ -295,7 +295,7 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
|
|||
DLOG << "APP_CMD_INIT_WINDOW";
|
||||
if (app->window != NULL) {
|
||||
platform->SetFrameRate(60);
|
||||
bool res = platform->renderer_->Initialize(app->window);
|
||||
bool res = platform->InitializeRenderer();
|
||||
CHECK(res) << "Failed to initialize "
|
||||
<< platform->renderer_->GetDebugName() << " renderer.";
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) {
|
|||
if (width != ANativeWindow_getWidth(app->window) ||
|
||||
height != ANativeWindow_getHeight(app->window)) {
|
||||
platform->renderer_->Shutdown();
|
||||
bool res = platform->renderer_->Initialize(platform->app_->window);
|
||||
bool res = platform->InitializeRenderer();
|
||||
CHECK(res) << "Failed to initialize "
|
||||
<< platform->renderer_->GetDebugName() << " renderer.";
|
||||
}
|
||||
|
@ -439,6 +439,10 @@ void Platform::SetFrameRate(float frame_rate) {
|
|||
}
|
||||
}
|
||||
|
||||
bool Platform::InitializeRenderer() {
|
||||
return renderer_->Initialize(app_->window);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
||||
void android_main(android_app* app) {
|
||||
|
|
|
@ -26,7 +26,7 @@ void Platform::Initialize() {
|
|||
bool res = CreateWindow(800, 1205);
|
||||
CHECK(res) << "Failed to create window.";
|
||||
|
||||
res = renderer_->Initialize(display_, window_);
|
||||
res = InitializeRenderer();
|
||||
CHECK(res) << "Failed to initialize " << renderer_->GetDebugName()
|
||||
<< " renderer.";
|
||||
|
||||
|
@ -157,6 +157,10 @@ void Platform::DestroyWindow() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Platform::InitializeRenderer() {
|
||||
return renderer_->Initialize(display_, window_);
|
||||
}
|
||||
|
||||
} // namespace eng
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
|
|
@ -48,6 +48,7 @@ RendererOpenGL::RendererOpenGL() = default;
|
|||
|
||||
RendererOpenGL::~RendererOpenGL() {
|
||||
Shutdown();
|
||||
OnDestroy();
|
||||
}
|
||||
|
||||
void RendererOpenGL::Shutdown() {
|
||||
|
|
|
@ -165,6 +165,8 @@ class RendererOpenGL final : public Renderer {
|
|||
bool InitCommon();
|
||||
void ShutdownInternal();
|
||||
|
||||
void OnDestroy();
|
||||
|
||||
void ContextLost();
|
||||
|
||||
void DestroyAllResources();
|
||||
|
|
|
@ -14,6 +14,10 @@ bool RendererOpenGL::Initialize(ANativeWindow* window) {
|
|||
return StartRenderThread();
|
||||
}
|
||||
|
||||
void RendererOpenGL::OnDestroy() {
|
||||
ndk_helper::GLContext::GetInstance()->Invalidate();
|
||||
}
|
||||
|
||||
bool RendererOpenGL::InitInternal() {
|
||||
ndk_helper::GLContext* gl_context = ndk_helper::GLContext::GetInstance();
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ bool RendererOpenGL::Initialize(Display* display, Window window) {
|
|||
return StartRenderThread();
|
||||
}
|
||||
|
||||
void RendererOpenGL::OnDestroy() {}
|
||||
|
||||
bool RendererOpenGL::InitInternal() {
|
||||
// Create the OpenGL context.
|
||||
glx_context_ =
|
||||
|
|
|
@ -15,6 +15,11 @@ class RenderResource {
|
|||
|
||||
uint64_t resource_id() { return resource_id_; }
|
||||
|
||||
void SetRenderer(Renderer* renderer) {
|
||||
renderer_ = renderer;
|
||||
resource_id_ = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint64_t resource_id_ = 0;
|
||||
Renderer* renderer_ = nullptr;
|
||||
|
|
Loading…
Reference in New Issue