Skip to content

Commit

Permalink
Extend sub-pixel rendering support (#2609)
Browse files Browse the repository at this point in the history
Implements sub-pixel rendering support for the SDL2 renderer. Achieved by replacing drawing functions in `SDLPainter` with their `float` equivalents.

Additionally, the `DrawingContext` size getters now return floating-point values, since before, they would always return an integer value, which didn't account for possible floating-point scale values of the current transform. This helps fix various other graphical glitches.

Fixes #2422.
  • Loading branch information
Vankata453 authored Aug 28, 2023
1 parent b59db06 commit 154315d
Show file tree
Hide file tree
Showing 42 changed files with 312 additions and 289 deletions.
8 changes: 5 additions & 3 deletions src/control/mobile_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ MobileController::draw(DrawingContext& context)
if (!g_config->mobile_controls)
return;

if (m_screen_width != context.get_width() || m_screen_height != context.get_height() || m_mobile_controls_scale != g_config->m_mobile_controls_scale)
if (m_screen_width != static_cast<int>(context.get_width()) ||
m_screen_height != static_cast<int>(context.get_height()) ||
m_mobile_controls_scale != g_config->m_mobile_controls_scale)
{
m_screen_width = context.get_width();
m_screen_height = context.get_height();
m_screen_width = static_cast<int>(context.get_width());
m_screen_height = static_cast<int>(context.get_height());
float width = static_cast<float>(m_screen_width);
float height = static_cast<float>(m_screen_height);
m_mobile_controls_scale = g_config->m_mobile_controls_scale;
Expand Down
4 changes: 2 additions & 2 deletions src/editor/overlay_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1353,8 +1353,8 @@ EditorOverlayWidget::draw_tile_grid(DrawingContext& context, int tile_size,
int tm_height = current_tm->get_height() * (32 / tile_size);
auto cam_translation = m_editor.get_sector()->get_camera().get_translation();
Rectf draw_rect = Rectf(cam_translation, cam_translation +
Vector(static_cast<float>(context.get_width() - 128),
static_cast<float>(context.get_height() - 32)));
Vector(context.get_width() - 128.f,
context.get_height() - 32.f));
Vector start = sp_to_tp( Vector(draw_rect.get_left(), draw_rect.get_top()), tile_size );
Vector end = sp_to_tp( Vector(draw_rect.get_right(), draw_rect.get_bottom()), tile_size );
start.x = std::max(0.0f, start.x);
Expand Down
8 changes: 4 additions & 4 deletions src/editor/toolbox_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ EditorToolboxWidget::draw(DrawingContext& context)
{
//SCREEN_WIDTH SCREEN_HEIGHT
context.color().draw_filled_rect(Rectf(Vector(static_cast<float>(m_Xpos), 0),
Vector(static_cast<float>(context.get_width()),
static_cast<float>(context.get_height()))),
Vector(context.get_width(),
context.get_height())),
g_config->editorcolor,
0.0f, LAYER_GUI-10);
if (m_dragging) {
Expand All @@ -97,10 +97,10 @@ EditorToolboxWidget::draw(DrawingContext& context)
}

context.color().draw_text(Resources::normal_font, _("Tiles"),
Vector(static_cast<float>(context.get_width()), 5),
Vector(context.get_width(), 5),
ALIGN_RIGHT, LAYER_GUI, ColorScheme::Menu::default_color);
context.color().draw_text(Resources::normal_font, _("Objects"),
Vector(static_cast<float>(context.get_width()), 37),
Vector(context.get_width(), 37),
ALIGN_RIGHT, LAYER_GUI, ColorScheme::Menu::default_color);

m_rubber->draw(context);
Expand Down
8 changes: 4 additions & 4 deletions src/gui/dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,11 @@ void
Dialog::draw(DrawingContext& context)
{
Rectf bg_rect(Vector(static_cast<float>(m_passive ?
(static_cast<float>(context.get_width()) - m_text_size.width - 20.0f) :
static_cast<float>(context.get_width()) / 2.0f - m_text_size.width / 2.0f),
(context.get_width() - m_text_size.width - 20.0f) :
context.get_width() / 2.0f - m_text_size.width / 2.0f),
static_cast<float>(m_passive ?
(static_cast<float>(context.get_height()) - m_text_size.height - 65.0f) :
(static_cast<float>(context.get_height()) / 2.0f - m_text_size.height / 2.0f))),
(context.get_height() - m_text_size.height - 65.0f) :
(context.get_height() / 2.0f - m_text_size.height / 2.0f))),
m_size);

// Draw background rect.
Expand Down
2 changes: 1 addition & 1 deletion src/gui/notification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Notification::draw(DrawingContext& context)
return;
}

m_pos = Vector(static_cast<float>(context.get_width()) - std::max(m_text_size.width, m_mini_text_size.width) - 90.0f,
m_pos = Vector(context.get_width() - std::max(m_text_size.width, m_mini_text_size.width) - 90.0f,
static_cast<float>(context.get_height() / 12) - m_text_size.height - m_mini_text_size.height + 10.0f);
Rectf bg_rect(m_pos, m_size);

Expand Down
33 changes: 15 additions & 18 deletions src/interface/control_scrollbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ ControlScrollbar::ControlScrollbar() :
m_covered_region(),
m_progress(),
m_rect(),
m_scaled_rect(),
//is_horizontal(),
last_mouse_pos()
//zoom_factor()
Expand All @@ -43,7 +42,7 @@ ControlScrollbar::ControlScrollbar() :
void
ControlScrollbar::draw(DrawingContext& context)
{
m_rect = Rect(0, 0, 10, context.get_height());
m_rect = Rectf(0, 0, 10, context.get_height());

context.color().draw_filled_rect(m_rect, Color(0.5f, 0.5f, 0.5f, 1.f), 8, LAYER_GUI);
context.color().draw_filled_rect(get_bar_rect(),
Expand Down Expand Up @@ -86,7 +85,7 @@ ControlScrollbar::on_mouse_button_down(const SDL_MouseButtonEvent& button)
{
if (button.button == SDL_BUTTON_LEFT) {
Vector mouse_pos = VideoSystem::current()->get_viewport().to_logical(button.x, button.y);
if (get_bar_rect().contains(int(mouse_pos.x), int(mouse_pos.y))) {
if (get_bar_rect().contains(mouse_pos)) {
m_scrolling = true;
return true;
} else {
Expand All @@ -112,7 +111,7 @@ ControlScrollbar::on_mouse_motion(const SDL_MouseMotionEvent& motion)
}
}*/

m_hovering = get_bar_rect().contains(int(mouse_pos.x), int(mouse_pos.y));
m_hovering = get_bar_rect().contains(mouse_pos);

int new_progress = m_progress + int((mouse_pos.y - last_mouse_pos) * VideoSystem::current()->get_viewport().get_scale().y * float(m_total_region) / float(m_covered_region));
last_mouse_pos = mouse_pos.y;
Expand All @@ -129,22 +128,20 @@ ControlScrollbar::on_mouse_motion(const SDL_MouseMotionEvent& motion)
}
}

Rect
Rectf
ControlScrollbar::get_bar_rect()
{
return Rect(m_rect.left,
m_rect.top + int(float(m_progress)
* float(m_covered_region)
/ float(m_total_region)
),
m_rect.right,
m_rect.top + int(float(m_progress)
* float(m_covered_region)
/ float(m_total_region))
+ int(float(m_rect.get_height())
* float(m_covered_region)
/ float(m_total_region)
)
return Rectf(m_rect.get_left(),
m_rect.get_top() + static_cast<float>(m_progress)
* static_cast<float>(m_covered_region)
/ static_cast<float>(m_total_region),
m_rect.get_right(),
m_rect.get_top() + static_cast<float>(m_progress)
* static_cast<float>(m_covered_region)
/ static_cast<float>(m_total_region)
+ m_rect.get_height()
* static_cast<float>(m_covered_region)
/ static_cast<float>(m_total_region)
);
}

Expand Down
10 changes: 4 additions & 6 deletions src/interface/control_scrollbar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
#define HEADER_SUPERTUX_INTERFACE_CONTROL_SCROLLBAR_HPP

#include "editor/widget.hpp"
#include "math/rect.hpp"

#include "math/rectf.hpp"
#include "math/vector.hpp"

class DrawingContext;
Expand Down Expand Up @@ -54,16 +55,13 @@ class ControlScrollbar final : public Widget
int m_progress;

/** The logical position and size of the widget */
Rect m_rect;

/** The position and size of the widget, to scale */
Rect m_scaled_rect;
Rectf m_rect;

/** `true` of the scroller is horizontal; `false` if it is vertical */
//bool is_horizontal;

private:
Rect get_bar_rect();
Rectf get_bar_rect();

float last_mouse_pos;
//float zoom_factor;
Expand Down
7 changes: 7 additions & 0 deletions src/math/rect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ Rect::Rect(const Rectf& other) :
{
}

Rectf
Rect::to_rectf() const
{
return { static_cast<float>(left), static_cast<float>(top),
static_cast<float>(get_width()), static_cast<float>(get_height()) };
}

std::ostream& operator<<(std::ostream& out, const Rect& rect)
{
out << "Rect("
Expand Down
8 changes: 7 additions & 1 deletion src/math/rect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class Rect final
top <= other.top && other.bottom <= bottom);
}

const int& get_left() const { return left; }
const int& get_right() const { return right; }
const int& get_top() const { return top; }
const int& get_bottom() const { return bottom; }

int get_width() const { return right - left; }
int get_height() const { return bottom - top; }
Size get_size() const { return Size(right - left, bottom - top); }
Expand Down Expand Up @@ -138,9 +143,10 @@ class Rect final
bottom + border);
}

Rectf to_rectf() const;
SDL_Rect to_sdl() const
{
return {left, top, get_width(), get_height()};
return { left, top, get_width(), get_height() };
}

bool operator<(const Rect& other) const {
Expand Down
7 changes: 7 additions & 0 deletions src/math/rectf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ Rectf::initialize()
}
}

Rect
Rectf::to_rect() const
{
return { static_cast<int>(m_p1.x), static_cast<int>(m_p1.y),
static_cast<int>(m_size.width), static_cast<int>(m_size.height) };
}

std::ostream& operator<<(std::ostream& out, const Rectf& rect)
{
out << "Rectf("
Expand Down
20 changes: 20 additions & 0 deletions src/math/rectf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include <assert.h>
#include <iosfwd>

#include <SDL.h>

#include "math/anchor_point.hpp"
#include "math/sizef.hpp"
#include "math/vector.hpp"
Expand Down Expand Up @@ -69,6 +71,12 @@ class Rectf final
initialize();
}

Rectf(const SDL_FRect& rect) :
m_p1(rect.x, rect.y), m_size(rect.w, rect.h)
{
initialize();
}

Rectf(const Rect& rect);

bool operator==(const Rectf& other) const
Expand Down Expand Up @@ -125,6 +133,12 @@ class Rectf final
}
Sizef get_size() const { return m_size; }

bool empty() const
{
return get_width() <= 0 ||
get_height() <= 0;
}

void move(const Vector& v) { m_p1 += v; }
Rectf moved(const Vector& v) const { return Rectf(m_p1 + v, m_size); }

Expand Down Expand Up @@ -179,6 +193,12 @@ class Rectf final
p.y - m_p1.y);
}

Rect to_rect() const;
SDL_FRect to_sdl() const
{
return { m_p1.x, m_p1.y, m_size.width, m_size.height };
}

private:
/// upper left edge
Vector m_p1;
Expand Down
16 changes: 8 additions & 8 deletions src/object/background.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ void
Background::draw_image(DrawingContext& context, const Vector& pos_)
{
const Sizef level(d_gameobject_manager->get_width(), d_gameobject_manager->get_height());
const Sizef screen(static_cast<float>(context.get_width()),
static_cast<float>(context.get_height()));
const Sizef screen(context.get_width(),
context.get_height());
const Sizef parallax_image_size((1.0f - m_parallax_speed.x) * screen.width + level.width * m_parallax_speed.x,
(1.0f - m_parallax_speed.y) * screen.height + level.height * m_parallax_speed.y);

Expand All @@ -301,10 +301,10 @@ Background::draw_image(DrawingContext& context, const Vector& pos_)

if (m_fill)
{
Rectf dstrect(Vector(pos_.x - static_cast<float>(context.get_width()) / 2.0f,
pos_.y - static_cast<float>(context.get_height()) / 2.0f),
Sizef(static_cast<float>(context.get_width()),
static_cast<float>(context.get_height())));
Rectf dstrect(Vector(pos_.x - context.get_width() / 2.0f,
pos_.y - context.get_height() / 2.0f),
Sizef(context.get_width(),
context.get_height()));
canvas.draw_surface_scaled(m_image, dstrect, m_layer);
}
else
Expand Down Expand Up @@ -384,8 +384,8 @@ Background::draw(DrawingContext& context)

Sizef level_size(d_gameobject_manager->get_width(),
d_gameobject_manager->get_height());
Sizef screen(static_cast<float>(context.get_width()),
static_cast<float>(context.get_height()));
Sizef screen(context.get_width(),
context.get_height());
Sizef translation_range = level_size - screen;
Vector center_offset(context.get_translation().x - translation_range.width / 2.0f,
context.get_translation().y - translation_range.height / 2.0f);
Expand Down
Loading

0 comments on commit 154315d

Please sign in to comment.