From ad678b5a1b7f457378b1d8ae7cdaf3ee7a08eb75 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 8 Sep 2021 10:38:28 +0200 Subject: Fix manga scroll view jumping, clamp to top/bottom, remove direct dependency on opengl --- src/ImageViewer.cpp | 59 +++++++++++++++---------------------- src/QuickMedia.cpp | 85 +---------------------------------------------------- src/Tabs.cpp | 18 ++++++++---- 3 files changed, 38 insertions(+), 124 deletions(-) (limited to 'src') diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp index 9bc177d..9c6abf7 100644 --- a/src/ImageViewer.cpp +++ b/src/ImageViewer.cpp @@ -85,7 +85,7 @@ namespace QuickMedia { std::shared_ptr &page_image_data = image_data[page]; const sf::Vector2 image_size = get_page_size(page); - sf::Vector2 render_pos(std::floor(window_size.x * 0.5 - image_size.x * 0.5), - image_size.y * 0.5 + scroll + offset_y); + sf::Vector2 render_pos(std::floor(window_size.x * 0.5 - image_size.x * 0.5), scroll + offset_y); if(render_pos.y + image_size.y <= 0.0 || render_pos.y >= window_size.y) { if(page_image_data) page_image_data->visible_on_screen = false; @@ -138,7 +138,7 @@ namespace QuickMedia { sf::Text error_message(std::move(msg), *font, 30 * get_config().scale * get_config().font_scale); auto text_bounds = error_message.getLocalBounds(); error_message.setFillColor(sf::Color::Black); - sf::Vector2 render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), - text_bounds.height * 0.5 + scroll + offset_y); + sf::Vector2 render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), image_size.y * 0.5 - text_bounds.height * 0.5 + scroll + offset_y); if(!scrolling) render_pos_text.y = std::floor(render_pos_text.y); @@ -157,7 +157,7 @@ namespace QuickMedia { sf::Text error_message("Downloading page " + page_str, *font, 30 * get_config().scale * get_config().font_scale); auto text_bounds = error_message.getLocalBounds(); error_message.setFillColor(sf::Color::Black); - sf::Vector2 render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), - text_bounds.height * 0.5 + scroll + offset_y); + sf::Vector2 render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), image_size.y * 0.5 - text_bounds.height * 0.5 + scroll + offset_y); if(!scrolling) render_pos_text.y = std::floor(render_pos_text.y); @@ -204,6 +204,12 @@ namespace QuickMedia { window_size.x = window_size_i.x; window_size.y = window_size_i.y; window_size_set = true; + + for(int i = 0; i < current_page; ++i) { + const sf::Vector2 size = get_page_size(i); + scroll -= size.y; + page_size[i].prev_size = size; + } } // TODO: Only redraw when scrolling and when image has finished downloading @@ -302,18 +308,11 @@ namespace QuickMedia { if(page_data->texture.loadFromImage(*page_data->image)) { page_data->texture.setSmooth(true); //page_data->texture.generateMipmap(); - double height_before = get_page_size(page_i).y; page_data->image_status = ImageStatus::APPLIED_TO_TEXTURE; page_data->sprite.setTexture(page_data->texture, true); sf::Vector2u texture_size = image_data[page_i]->texture.getSize(); page_size[page_i].size = sf::Vector2(texture_size.x, texture_size.y); page_size[page_i].loaded = true; - double height_after = get_page_size(page_i).y; - - double height_diff = height_before - height_after; - if(scroll_speed <= 0.0 && page_i < current_page) { - scroll -= height_diff; - } } else { page_data->image_status = ImageStatus::FAILED_TO_LOAD; } @@ -325,33 +324,23 @@ namespace QuickMedia { ++page_i; } - const sf::Vector2 selected_page_size = get_page_size(current_page); - render_page(*window, current_page, window_size.y*0.5); - //if(!focused_page_rendered) - // return; - - // Render previous pages - double page_offset = window_size.y*0.5 - selected_page_size.y*0.5; - int page = current_page - 1; - while(true) { - const sf::Vector2 image_size = get_page_size(page); - page_offset -= image_size.y*0.5; - if(!render_page(*window, page, page_offset)) - break; - --page; - page_offset -= image_size.y*0.5; + double page_offset = 0.0; + for(int i = 0; i < num_pages; ++i) { + const sf::Vector2 current_page_size = get_page_size(i); + const double scroll_diff = current_page_size.y - page_size[i].prev_size.y; + page_size[i].prev_size = current_page_size; + + if(page_offset < -scroll) + scroll -= scroll_diff; + + render_page(*window, i, page_offset); + page_offset += current_page_size.y; } - // Render next pages - page_offset = window_size.y*0.5 + selected_page_size.y*0.5; - page = current_page + 1; - while(true) { - const sf::Vector2 image_size = get_page_size(page); - page_offset += image_size.y*0.5; - if(!render_page(*window, page, page_offset)) - break; - ++page; - page_offset += image_size.y*0.5; + if(scroll > 0.0) { + scroll = 0.0; + } else if(scroll + page_offset < window_size.y && page_offset > window_size.y) { + scroll += (window_size.y - (scroll + page_offset)); } if(page_closest_to_center != -1) { diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index fc9db2f..d06a0b7 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -55,7 +55,6 @@ #include #include #include -#include static int FPS_IDLE; static const double IDLE_TIMEOUT_SEC = 2.0; @@ -175,79 +174,6 @@ static void get_screen_resolution(Display *display, int *width, int *height) { *height = DefaultScreenOfDisplay(display)->height; } -static bool has_gl_ext(Display *disp, const char *ext) { - const char *extensions = glXQueryExtensionsString(disp, DefaultScreen(disp)); - if(!extensions) - return false; - - int ext_len = strlen(ext); - while(true) { - const char *loc = strstr(extensions, ext); - if(!loc) - return false; - - const char *terminator = loc + ext_len; - if((loc == extensions || *(loc - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) - return true; - - extensions = terminator; - } -} - -static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA = nullptr; -static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; -static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; -static bool vsync_loaded = false; -static bool vsync_set = false; - -static bool test_vsync(Display *disp, Window window) { - unsigned int swap = 0; - glXQueryDrawable(disp, window, GLX_SWAP_INTERVAL_EXT, &swap); - fprintf(stderr, "The swap interval is %u\n", swap); - return swap == 1; -} - -static bool enable_vsync(Display *disp, Window window) { - if(vsync_loaded) { - if(glXSwapIntervalMESA) - return glXSwapIntervalMESA(1) == 0; - if(glXSwapIntervalSGI) - return glXSwapIntervalSGI(1) == 0; - if(glXSwapIntervalEXT) { - glXSwapIntervalEXT(disp, window, 1); - return true; - } - return false; - } - vsync_loaded = true; - - if(has_gl_ext(disp, "GLX_MESA_swap_control")) { - fprintf(stderr, "vsync method: GLX_MESA_swap_control\n"); - glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); - if(glXSwapIntervalMESA && glXSwapIntervalMESA(1) == 0 && test_vsync(disp, window)) - return true; - } - - if(has_gl_ext(disp, "GLX_SGI_swap_control")) { - fprintf(stderr, "vsync method: GLX_SGI_swap_control\n"); - glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); - if(glXSwapIntervalSGI && glXSwapIntervalSGI(1) == 0 && test_vsync(disp, window)) - return true; - } - - if(has_gl_ext(disp, "GLX_EXT_swap_control")) { - fprintf(stderr, "vsync method: GLX_EXT_swap_control\n"); - glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); - if(glXSwapIntervalEXT) { - glXSwapIntervalEXT(disp, window, 1); - return test_vsync(disp, window); - } - } - - fprintf(stderr, "vsync method: none\n"); - return false; -} - static sf::Color interpolate_colors(sf::Color source, sf::Color target, double progress) { int diff_r = (int)target.r - (int)source.r; int diff_g = (int)target.g - (int)source.g; @@ -711,19 +637,10 @@ namespace QuickMedia { XSetErrorHandler(x_error_handler); XSetIOErrorHandler(x_io_error_handler); - window.setVerticalSyncEnabled(true); + window.setVerticalSyncEnabled(false); monitor_hz = get_monitor_max_hz(disp); window.setFramerateLimit(monitor_hz); idle = false; - vsync_set = false; - /* - if(enable_vsync(disp, window.getSystemHandle())) { - vsync_set = true; - } else { - fprintf(stderr, "Failed to enable vsync, fallback to frame limiting\n"); - window.setFramerateLimit(monitor_hz); - } - */ fprintf(stderr, "Monitor hz: %d\n", monitor_hz); if(create_directory_recursive(get_cache_dir().join("media")) != 0) { diff --git a/src/Tabs.cpp b/src/Tabs.cpp index 3745973..8965a85 100644 --- a/src/Tabs.cpp +++ b/src/Tabs.cpp @@ -5,7 +5,6 @@ #include "../include/Theme.hpp" #include #include -#include #include namespace QuickMedia { @@ -83,6 +82,14 @@ namespace QuickMedia { } } + static sf::View create_scissor_view(sf::Vector2f pos, sf::Vector2f size, const sf::Vector2f window_size) { + sf::View view(sf::FloatRect(0.0f, 0.0f, size.x, size.y)); + view.setViewport(sf::FloatRect( + pos.x / (float)window_size.x, pos.y / (float)window_size.y, + size.x / (float)window_size.x, size.y / (float)window_size.y)); + return view; + } + void Tabs::draw(sf::RenderWindow &window, sf::Vector2f pos, float width) { if(width - tab_margin_x < 0.0f || tabs.empty()) return; @@ -118,6 +125,8 @@ namespace QuickMedia { bool tabs_cutoff_right = false; const auto start_pos = pos; + const sf::View prev_view = window.getView(); + pos.x += scroll_fixed; for(size_t i = 0; i < tabs.size(); ++i) { const int index = i; @@ -138,11 +147,10 @@ namespace QuickMedia { sf::Text &tab_text = tabs[index].text; float text_pos_x = std::floor(pos.x + i*width_per_tab + width_per_tab*0.5f - tab_text.getLocalBounds().width*0.5f); text_pos_x = std::max(text_pos_x, background_pos_x); - tab_text.setPosition(text_pos_x, tab_text_y); - glEnable(GL_SCISSOR_TEST); - glScissor(text_pos_x, (int)window_size.y - (int)tab_text_y - (int)tab_height, tab_background_width, tab_height); + + window.setView(create_scissor_view({ text_pos_x, tab_text_y }, { tab_background_width, tab_height }, { (float)window_size.x, (float)window_size.y })); window.draw(tab_text); - glDisable(GL_SCISSOR_TEST); + window.setView(prev_view); } float lw = std::floor(25.0f * get_config().scale); -- cgit v1.2.3