Implement window resize

This commit is contained in:
Attila Uygun 2023-07-01 21:36:26 +02:00
parent c6546b43b5
commit 3dc48ef05e
12 changed files with 90 additions and 49 deletions

View File

@ -113,18 +113,7 @@ void Engine::Initialize() {
CreateRendererInternal(RendererType::kVulkan);
// Normalize viewport.
if (GetScreenWidth() > GetScreenHeight()) {
float aspect_ratio = (float)GetScreenWidth() / (float)GetScreenHeight();
LOG(0) << "aspect ratio: " << aspect_ratio;
screen_size_ = {aspect_ratio * 2.0f, 2.0f};
projection_.CreateOrthoProjection(-aspect_ratio, aspect_ratio, -1.0f, 1.0f);
} else {
float aspect_ratio = (float)GetScreenHeight() / (float)GetScreenWidth();
LOG(0) << "aspect_ratio: " << aspect_ratio;
screen_size_ = {2.0f, aspect_ratio * 2.0f};
projection_.CreateOrthoProjection(-1.0, 1.0, -aspect_ratio, aspect_ratio);
}
CreateProjectionMatrix();
LOG(0) << "image scale factor: " << GetImageScaleFactor();
@ -458,11 +447,11 @@ TextureCompressor* Engine::GetTextureCompressor(bool opacity) {
}
int Engine::GetScreenWidth() const {
return renderer_->screen_width();
return renderer_->GetScreenWidth();
}
int Engine::GetScreenHeight() const {
return renderer_->screen_height();
return renderer_->GetScreenHeight();
}
int Engine::GetDeviceDpi() const {
@ -470,7 +459,7 @@ int Engine::GetDeviceDpi() const {
}
float Engine::GetImageScaleFactor() const {
float width_inch = static_cast<float>(renderer_->screen_width()) /
float width_inch = static_cast<float>(renderer_->GetScreenWidth()) /
static_cast<float>(platform_->GetDeviceDpi());
return 2.57143f / width_inch;
}
@ -504,10 +493,10 @@ void Engine::OnWindowDestroyed() {
}
void Engine::OnWindowResized(int width, int height) {
if (width != renderer_->screen_width() ||
height != renderer_->screen_height()) {
renderer_->Shutdown();
renderer_->Initialize(platform_);
if (width != renderer_->GetScreenWidth() ||
height != renderer_->GetScreenHeight()) {
renderer_->OnWindowResized(width, height);
CreateProjectionMatrix();
}
}
@ -615,6 +604,20 @@ void Engine::CreateTextureCompressors() {
}
}
void Engine::CreateProjectionMatrix() {
if (GetScreenWidth() > GetScreenHeight()) {
float aspect_ratio = (float)GetScreenWidth() / (float)GetScreenHeight();
LOG(0) << "aspect ratio: " << aspect_ratio;
screen_size_ = {aspect_ratio * 2.0f, 2.0f};
projection_.CreateOrthoProjection(-aspect_ratio, aspect_ratio, -1.0f, 1.0f);
} else {
float aspect_ratio = (float)GetScreenHeight() / (float)GetScreenWidth();
LOG(0) << "aspect_ratio: " << aspect_ratio;
screen_size_ = {2.0f, aspect_ratio * 2.0f};
projection_.CreateOrthoProjection(-1.0, 1.0, -aspect_ratio, aspect_ratio);
}
}
void Engine::ContextLost() {
CreateRenderResources();
WaitForAsyncWork();

View File

@ -239,6 +239,8 @@ class Engine : public PlatformObserver {
void CreateTextureCompressors();
void CreateProjectionMatrix();
void ContextLost();
void CreateRenderResources();

View File

@ -30,7 +30,7 @@ Platform::Platform() {
XSelectInput(display_, window_,
KeyPressMask | Button1MotionMask | ButtonPressMask |
ButtonReleaseMask | FocusChangeMask);
ButtonReleaseMask | FocusChangeMask | StructureNotifyMask);
Atom WM_DELETE_WINDOW = XInternAtom(display_, "WM_DELETE_WINDOW", false);
XSetWMProtocols(display_, window_, &WM_DELETE_WINDOW, 1);
}
@ -91,6 +91,10 @@ void Platform::Update() {
should_exit_ = true;
break;
}
case ConfigureNotify: {
XConfigureEvent xce = e.xconfigure;
observer_->OnWindowResized(xce.width, xce.height);
}
}
}
}

View File

@ -46,6 +46,20 @@ void RendererOpenGL::Shutdown() {
ShutdownInternal();
}
void RendererOpenGL::OnWindowResized(int width, int height) {
screen_width_ = width;
screen_height_ = height;
glViewport(0, 0, screen_width_, screen_height_);
}
int RendererOpenGL::GetScreenWidth() const {
return screen_width_;
}
int RendererOpenGL::GetScreenHeight() const {
return screen_height_;
}
uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr<Mesh> mesh) {
// Verify that we have a valid layout and get the total byte size per vertex.
GLuint vertex_size = mesh->GetVertexSize();
@ -483,8 +497,6 @@ bool RendererOpenGL::InitCommon() {
LOG(0) << " etc1: " << texture_compression_.etc1;
LOG(0) << " s3tc: " << texture_compression_.s3tc;
glViewport(0, 0, screen_width_, screen_height_);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

View File

@ -25,6 +25,11 @@ class RendererOpenGL final : public Renderer {
bool IsInitialzed() const final { return is_initialized_; }
void OnWindowResized(int width, int height) final;
int GetScreenWidth() const final;
int GetScreenHeight() const final;
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
void DestroyGeometry(uint64_t resource_id) final;
void Draw(uint64_t resource_id) final;
@ -109,6 +114,9 @@ class RendererOpenGL final : public Renderer {
// Stats.
size_t fps_ = 0;
int screen_width_ = 0;
int screen_height_ = 0;
#if defined(__ANDROID__)
ANativeWindow* window_;
#elif defined(__linux__)

View File

@ -11,11 +11,6 @@ bool RendererOpenGL::Initialize(Platform* platform) {
display_ = platform->GetDisplay();
window_ = platform->GetWindow();
XWindowAttributes xwa;
XGetWindowAttributes(display_, window_, &xwa);
screen_width_ = xwa.width;
screen_height_ = xwa.height;
GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER,
None};
XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes);
@ -32,6 +27,10 @@ bool RendererOpenGL::Initialize(Platform* platform) {
return false;
}
XWindowAttributes xwa;
XGetWindowAttributes(display_, window_, &xwa);
OnWindowResized(xwa.width, xwa.height);
return InitCommon();
}

View File

@ -30,6 +30,11 @@ class Renderer {
virtual bool IsInitialzed() const = 0;
virtual void OnWindowResized(int width, int height) = 0;
virtual int GetScreenWidth() const = 0;
virtual int GetScreenHeight() const = 0;
virtual uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) = 0;
virtual void DestroyGeometry(uint64_t resource_id) = 0;
virtual void Draw(uint64_t resource_id) = 0;
@ -77,9 +82,6 @@ class Renderer {
bool SupportsDXT5() const { return texture_compression_.s3tc; }
bool SupportsATC() const { return texture_compression_.atc; }
int screen_width() const { return screen_width_; }
int screen_height() const { return screen_height_; }
virtual size_t GetAndResetFPS() = 0;
virtual const char* GetDebugName() = 0;
@ -106,9 +108,6 @@ class Renderer {
TextureCompression texture_compression_;
int screen_width_ = 0;
int screen_height_ = 0;
base::Closure context_lost_cb_;
Renderer(const Renderer&) = delete;

View File

@ -377,6 +377,18 @@ RendererVulkan::~RendererVulkan() {
Shutdown();
}
void RendererVulkan::OnWindowResized(int width, int height) {
context_.ResizeWindow(width, height);
}
int RendererVulkan::GetScreenWidth() const {
return context_.GetWindowWidth();
}
int RendererVulkan::GetScreenHeight() const {
return context_.GetWindowHeight();
}
uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
auto& geometry = geometries_[++last_resource_id_] = {};
@ -1915,8 +1927,8 @@ void RendererVulkan::DrawListBegin() {
render_pass_begin.renderPass = context_.GetRenderPass();
render_pass_begin.framebuffer = context_.GetFramebuffer();
render_pass_begin.renderArea.extent.width = screen_width_;
render_pass_begin.renderArea.extent.height = screen_height_;
render_pass_begin.renderArea.extent.width = context_.GetWindowWidth();
render_pass_begin.renderArea.extent.height = context_.GetWindowHeight();
render_pass_begin.renderArea.offset.x = 0;
render_pass_begin.renderArea.offset.y = 0;
@ -1932,9 +1944,9 @@ void RendererVulkan::DrawListBegin() {
VkViewport viewport;
viewport.x = 0;
viewport.y = (float)screen_height_;
viewport.width = (float)screen_width_;
viewport.height = -(float)screen_height_;
viewport.y = (float)context_.GetWindowHeight();
viewport.width = (float)context_.GetWindowWidth();
viewport.height = -(float)context_.GetWindowHeight();
viewport.minDepth = 0;
viewport.maxDepth = 1.0;
@ -1943,8 +1955,8 @@ void RendererVulkan::DrawListBegin() {
VkRect2D scissor;
scissor.offset.x = 0;
scissor.offset.y = 0;
scissor.extent.width = screen_width_;
scissor.extent.height = screen_height_;
scissor.extent.width = context_.GetWindowWidth();
scissor.extent.height = context_.GetWindowHeight();
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
}

View File

@ -28,6 +28,11 @@ class RendererVulkan final : public Renderer {
bool IsInitialzed() const final { return device_ != VK_NULL_HANDLE; }
void OnWindowResized(int width, int height) final;
int GetScreenWidth() const final;
int GetScreenHeight() const final;
uint64_t CreateGeometry(std::unique_ptr<Mesh> mesh) final;
void DestroyGeometry(uint64_t resource_id) final;
void Draw(uint64_t resource_id) final;

View File

@ -10,15 +10,14 @@ namespace eng {
bool RendererVulkan::Initialize(Platform* platform) {
LOG(0) << "Initializing renderer.";
screen_width_ = ANativeWindow_getWidth(platform->GetWindow());
screen_height_ = ANativeWindow_getHeight(platform->GetWindow());
int width = ANativeWindow_getWidth(platform->GetWindow());
int height = ANativeWindow_getHeight(platform->GetWindow());
if (!context_.Initialize()) {
LOG(0) << "Failed to initialize Vulkan context.";
return false;
}
if (!context_.CreateWindow(platform->GetWindow(), screen_width_,
screen_height_)) {
if (!context_.CreateWindow(platform->GetWindow(), width, height)) {
LOG(0) << "Vulkan context failed to create window.";
return false;
}

View File

@ -10,15 +10,13 @@ bool RendererVulkan::Initialize(Platform* platform) {
XWindowAttributes xwa;
XGetWindowAttributes(platform->GetDisplay(), platform->GetWindow(), &xwa);
screen_width_ = xwa.width;
screen_height_ = xwa.height;
if (!context_.Initialize()) {
LOG(0) << "Failed to initialize Vulkan context.";
return false;
}
if (!context_.CreateWindow(platform->GetDisplay(), platform->GetWindow(),
screen_width_, screen_height_)) {
xwa.width, xwa.height)) {
LOG(0) << "Vulkan context failed to create window.";
return false;
}

View File

@ -58,8 +58,8 @@ class VulkanContext {
VkPhysicalDeviceLimits GetDeviceLimits() const { return gpu_props_.limits; }
int GetWidth() { return window_.width; }
int GetHeight() { return window_.height; }
int GetWindowWidth() const { return window_.width; }
int GetWindowHeight() const { return window_.height; }
size_t GetAndResetFPS();