Correctly render flipped/rotated screens
This commit is contained in:
parent
2a896eae5f
commit
bd8fc3f7d4
28
src/main.c
28
src/main.c
@ -347,6 +347,21 @@ static inline void color_to_float_array(GtkStyleContext *ctx,
|
|||||||
out[3] = color.alpha;
|
out[3] = color.alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned form_get_rotation(GtkWidget *form) {
|
||||||
|
GtkBuilder *builder = GTK_BUILDER(g_object_get_data(G_OBJECT(form), "builder"));
|
||||||
|
unsigned rot;
|
||||||
|
for (rot = 0; rot < NUM_ROTATIONS; rot++) {
|
||||||
|
GtkWidget *rotate = GTK_WIDGET(gtk_builder_get_object(builder,
|
||||||
|
ROTATE_IDS[rot]));
|
||||||
|
gboolean selected;
|
||||||
|
g_object_get(rotate, "active", &selected, NULL);
|
||||||
|
if (selected) {
|
||||||
|
return rot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static void queue_canvas_draw(struct wd_state *state) {
|
static void queue_canvas_draw(struct wd_state *state) {
|
||||||
GtkStyleContext *style_ctx = gtk_widget_get_style_context(state->canvas);
|
GtkStyleContext *style_ctx = gtk_widget_get_style_context(state->canvas);
|
||||||
color_to_float_array(style_ctx,
|
color_to_float_array(style_ctx,
|
||||||
@ -379,6 +394,13 @@ static void queue_canvas_draw(struct wd_state *state) {
|
|||||||
wl_list_insert(&state->render.heads, &head->render->link);
|
wl_list_insert(&state->render.heads, &head->render->link);
|
||||||
}
|
}
|
||||||
struct wd_render_head_data *render = head->render;
|
struct wd_render_head_data *render = head->render;
|
||||||
|
render->queued.rotation = form_get_rotation(GTK_WIDGET(form_iter->data));
|
||||||
|
if (render->queued.rotation & 1) {
|
||||||
|
int tmp = w;
|
||||||
|
w = h;
|
||||||
|
h = tmp;
|
||||||
|
}
|
||||||
|
render->queued.x_invert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "flipped")));
|
||||||
render->x1 = floor(x * state->zoom - state->render.scroll_x - state->render.x_origin);
|
render->x1 = floor(x * state->zoom - state->render.scroll_x - state->render.x_origin);
|
||||||
render->y1 = floor(y * state->zoom - state->render.scroll_y - state->render.y_origin);
|
render->y1 = floor(y * state->zoom - state->render.scroll_y - state->render.y_origin);
|
||||||
render->x2 = floor(render->x1 + w * state->zoom / scale);
|
render->x2 = floor(render->x1 + w * state->zoom / scale);
|
||||||
@ -839,6 +861,10 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
|||||||
render->y_invert = frame->y_invert;
|
render->y_invert = frame->y_invert;
|
||||||
render->swap_rgb = frame->swap_rgb;
|
render->swap_rgb = frame->swap_rgb;
|
||||||
}
|
}
|
||||||
|
if (render->preview) {
|
||||||
|
render->active.rotation = render->queued.rotation;
|
||||||
|
render->active.x_invert = render->queued.x_invert;
|
||||||
|
}
|
||||||
} else if (render->preview
|
} else if (render->preview
|
||||||
|| render->pixels == NULL || size_changed(render)) {
|
|| render->pixels == NULL || size_changed(render)) {
|
||||||
render->tex_width = render->x2 - render->x1;
|
render->tex_width = render->x2 - render->x1;
|
||||||
@ -852,6 +878,8 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
|||||||
render->pixels = cairo_image_surface_get_data(head->surface);
|
render->pixels = cairo_image_surface_get_data(head->surface);
|
||||||
render->tex_stride = cairo_image_surface_get_stride(head->surface);
|
render->tex_stride = cairo_image_surface_get_stride(head->surface);
|
||||||
render->updated_at = tick;
|
render->updated_at = tick;
|
||||||
|
render->active.rotation = 0;
|
||||||
|
render->active.x_invert = false;
|
||||||
render->y_invert = false;
|
render->y_invert = false;
|
||||||
render->swap_rgb = false;
|
render->swap_rgb = false;
|
||||||
}
|
}
|
||||||
|
43
src/render.c
43
src/render.c
@ -253,20 +253,39 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info,
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
wl_list_for_each_reverse(head, &info->heads, link) {
|
wl_list_for_each_reverse(head, &info->heads, link) {
|
||||||
float *tri_ptr = res->tris + i * BT_UV_QUAD_SIZE;
|
float *tri_ptr = res->tris + i * BT_UV_QUAD_SIZE;
|
||||||
float x1 = head->x1;
|
float x1 = head->active.x_invert ? head->x2 : head->x1;
|
||||||
float y1 = head->y1;
|
float y1 = head->y_invert ? head->y2 : head->y1;
|
||||||
float x2 = head->x2;
|
float x2 = head->active.x_invert ? head->x1 : head->x2;
|
||||||
float y2 = head->y2;
|
float y2 = head->y_invert ? head->y1 : head->y2;
|
||||||
|
|
||||||
float t1 = head->y_invert ? 1.f : 0.f;
|
float sa = 0.f;
|
||||||
float t2 = head->y_invert ? 0.f : 1.f;
|
float sb = 1.f;
|
||||||
|
float sc = sb;
|
||||||
|
float sd = sa;
|
||||||
|
float ta = 0.f;
|
||||||
|
float tb = ta;
|
||||||
|
float tc = 1.f;
|
||||||
|
float td = tc;
|
||||||
|
for (int i = 0; i < head->active.rotation; i++) {
|
||||||
|
float tmp = sd;
|
||||||
|
sd = sc;
|
||||||
|
sc = sb;
|
||||||
|
sb = sa;
|
||||||
|
sa = tmp;
|
||||||
|
|
||||||
PUSH_POINT_UV(tri_ptr, x1, y1, 0.f, t1)
|
tmp = td;
|
||||||
PUSH_POINT_UV(tri_ptr, x2, y1, 1.f, t1)
|
td = tc;
|
||||||
PUSH_POINT_UV(tri_ptr, x1, y2, 0.f, t2)
|
tc = tb;
|
||||||
PUSH_POINT_UV(tri_ptr, x1, y2, 0.f, t2)
|
tb = ta;
|
||||||
PUSH_POINT_UV(tri_ptr, x2, y1, 1.f, t1)
|
ta = tmp;
|
||||||
PUSH_POINT_UV(tri_ptr, x2, y2, 1.f, t2)
|
}
|
||||||
|
|
||||||
|
PUSH_POINT_UV(tri_ptr, x1, y1, sa, ta)
|
||||||
|
PUSH_POINT_UV(tri_ptr, x2, y1, sb, tb)
|
||||||
|
PUSH_POINT_UV(tri_ptr, x1, y2, sd, td)
|
||||||
|
PUSH_POINT_UV(tri_ptr, x1, y2, sd, td)
|
||||||
|
PUSH_POINT_UV(tri_ptr, x2, y1, sb, tb)
|
||||||
|
PUSH_POINT_UV(tri_ptr, x2, y2, sc, tc)
|
||||||
|
|
||||||
tris += 6;
|
tris += 6;
|
||||||
i++;
|
i++;
|
||||||
|
@ -148,25 +148,33 @@ struct wd_head {
|
|||||||
|
|
||||||
struct wd_gl_data;
|
struct wd_gl_data;
|
||||||
|
|
||||||
|
struct wd_render_head_flags {
|
||||||
|
uint8_t rotation;
|
||||||
|
bool x_invert;
|
||||||
|
};
|
||||||
|
|
||||||
struct wd_render_head_data {
|
struct wd_render_head_data {
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
uint64_t updated_at;
|
||||||
|
uint64_t transition_begin;
|
||||||
|
|
||||||
float x1;
|
float x1;
|
||||||
float y1;
|
float y1;
|
||||||
float x2;
|
float x2;
|
||||||
float y2;
|
float y2;
|
||||||
|
|
||||||
|
struct wd_render_head_flags queued;
|
||||||
|
struct wd_render_head_flags active;
|
||||||
|
|
||||||
uint8_t *pixels;
|
uint8_t *pixels;
|
||||||
unsigned tex_stride;
|
unsigned tex_stride;
|
||||||
unsigned tex_width;
|
unsigned tex_width;
|
||||||
unsigned tex_height;
|
unsigned tex_height;
|
||||||
|
|
||||||
bool preview;
|
bool preview;
|
||||||
bool y_invert;
|
bool y_invert;
|
||||||
bool swap_rgb;
|
bool swap_rgb;
|
||||||
uint64_t updated_at;
|
|
||||||
|
|
||||||
bool hovered;
|
bool hovered;
|
||||||
uint64_t transition_begin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wd_render_data {
|
struct wd_render_data {
|
||||||
|
Loading…
Reference in New Issue
Block a user