viewport scaling by camera size
This commit is contained in:
parent
b53dfe93f8
commit
c6ca5c0c9a
@ -5,8 +5,9 @@
|
||||
* system. */
|
||||
#define RESOURCES_EMBEDDED !(DEVELOPER)
|
||||
|
||||
//#define ASPECT_RATIO (16.0 / 9.0)
|
||||
#define ASPECT_RATIO (4.0 / 3.0)
|
||||
#define DEFAULT_CAMERA_WIDTH (6)
|
||||
#define DEFAULT_CAMERA_ASPECT_RATIO (16.0 / 9.0)
|
||||
|
||||
#define PIXELS_PER_UNIT 256
|
||||
|
||||
#define GAME_FPS 50
|
||||
|
||||
@ -95,7 +95,7 @@ struct entity {
|
||||
/* ENTITY_PROP_CAMERA */
|
||||
struct entity_handle camera_follow;
|
||||
struct xform camera_target_xform; /* Calculated from camera_follow */
|
||||
f32 camera_zoom;
|
||||
struct v2 camera_size;
|
||||
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
||||
u32 camera_lerp_gen;
|
||||
u32 camera_applied_lerp_gen_plus_one; /* Calculated */
|
||||
|
||||
11
src/game.c
11
src/game.c
@ -205,7 +205,10 @@ INTERNAL void game_update(void)
|
||||
entity_enable_prop(e, ENTITY_PROP_CAMERA);
|
||||
entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE);
|
||||
e->camera_follow = player_ent->handle;
|
||||
e->camera_zoom = 1;
|
||||
|
||||
f32 width = (f32)DEFAULT_CAMERA_WIDTH;
|
||||
f32 height = width / (f32)DEFAULT_CAMERA_ASPECT_RATIO;
|
||||
e->camera_size = V2(width, height);
|
||||
}
|
||||
|
||||
/* Sound ent */
|
||||
@ -473,8 +476,12 @@ INTERNAL void game_update(void)
|
||||
ent->camera_target_xform.og = target_pos;
|
||||
#else
|
||||
/* "Look" style camera */
|
||||
f32 aspect_ratio = 1.0;
|
||||
if (!v2_eq(ent->camera_size, V2(0, 0))) {
|
||||
aspect_ratio = ent->camera_size.x / ent->camera_size.y;
|
||||
}
|
||||
f32 ratio_y = 0.33f;
|
||||
f32 ratio_x = ratio_y / (f32)ASPECT_RATIO;
|
||||
f32 ratio_x = ratio_y / aspect_ratio;
|
||||
struct v2 camera_focus_dir = v2_mul_v2(follow->player_aim, V2(ratio_x, ratio_y));
|
||||
struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir);
|
||||
ent->camera_target_xform.og = camera_focus_pos;
|
||||
|
||||
@ -655,7 +655,6 @@ void renderer_canvas_release(struct renderer_canvas *canvas)
|
||||
arena_release(&buffer->index_arena);
|
||||
|
||||
/* FIXME: Clear GPU buffers */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ struct sys_window_settings settings_default_window_settings(struct sys_window *w
|
||||
struct v2 monitor_size = sys_window_get_monitor_size(window);
|
||||
|
||||
i32 width = 1280;
|
||||
i32 height = math_round(width / (f32)ASPECT_RATIO);
|
||||
i32 height = math_round(width / (f32)DEFAULT_CAMERA_ASPECT_RATIO);
|
||||
i32 x = math_round(monitor_size.x / 2.f - width / 2);
|
||||
i32 y = math_round(monitor_size.y / 2.f - height / 2);
|
||||
|
||||
|
||||
87
src/user.c
87
src/user.c
@ -38,7 +38,6 @@ GLOBAL struct {
|
||||
struct renderer_canvas *world_canvas;
|
||||
struct renderer_canvas *viewport_bg_canvas;
|
||||
struct renderer_canvas *viewport_canvas;
|
||||
struct xform world_view_last_frame;
|
||||
struct xform world_view;
|
||||
|
||||
struct blend_tick *head_free_blend_tick;
|
||||
@ -342,34 +341,8 @@ INTERNAL void user_update(void)
|
||||
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
|
||||
L.dt = max_f64(0.0, cur_time - L.time);
|
||||
L.time += L.dt;
|
||||
|
||||
/* Calculate screen & viewport dimensions */
|
||||
{
|
||||
/* Get screen dimensions */
|
||||
L.screen_size = sys_window_get_size(L.window);
|
||||
|
||||
/* Enforce viewport at aspect ratio */
|
||||
f32 aspect_ratio = ASPECT_RATIO;
|
||||
f32 width = L.screen_size.x;
|
||||
f32 height = L.screen_size.y;
|
||||
if (width / height > aspect_ratio) {
|
||||
width = height * aspect_ratio;
|
||||
} else {
|
||||
height = (f32)math_ceil(width / aspect_ratio);
|
||||
}
|
||||
L.viewport_size = V2(width, height);
|
||||
|
||||
/* Center viewport in window */
|
||||
f32 x = 0;
|
||||
f32 y = 0;
|
||||
x = math_round(L.screen_size.x / 2 - width / 2);
|
||||
y = math_round(L.screen_size.y / 2 - height / 2);
|
||||
L.viewport_screen_offset = V2(x, y);
|
||||
|
||||
/* Get center */
|
||||
L.viewport_center = v2_mul(L.viewport_size, 0.5);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Produce interpolated tick
|
||||
* ========================== */
|
||||
@ -426,7 +399,7 @@ INTERNAL void user_update(void)
|
||||
e->sprite_xform = xform_lerp(e0->sprite_xform, e1->sprite_xform, tick_blend);
|
||||
e->animation_time_in_frame = math_lerp_f64(e0->animation_time_in_frame, e1->animation_time_in_frame, (f64)tick_blend);
|
||||
|
||||
e->camera_zoom = math_lerp(e0->camera_zoom, e1->camera_zoom, tick_blend);
|
||||
e->camera_size = v2_lerp(e0->camera_size, e1->camera_size, tick_blend);
|
||||
e->camera_target_xform = xform_lerp(e0->camera_target_xform, e1->camera_target_xform, tick_blend);
|
||||
}
|
||||
}
|
||||
@ -497,7 +470,6 @@ INTERNAL void user_update(void)
|
||||
/* Update mouse pos */
|
||||
if (event->kind == SYS_EVENT_KIND_CURSOR_MOVE) {
|
||||
L.screen_cursor = event->cursor_position;
|
||||
L.viewport_cursor = v2_sub(L.screen_cursor, L.viewport_screen_offset);;
|
||||
}
|
||||
|
||||
/* Update bind states */
|
||||
@ -548,12 +520,6 @@ INTERNAL void user_update(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Update view
|
||||
* ========================== */
|
||||
|
||||
L.world_view_last_frame = L.world_view;
|
||||
|
||||
if (L.bind_states[USER_BIND_KIND_DEBUG_DRAW].num_presses > 0) {
|
||||
L.debug_draw = !L.debug_draw;
|
||||
}
|
||||
@ -562,6 +528,46 @@ INTERNAL void user_update(void)
|
||||
L.debug_camera = !L.debug_camera;
|
||||
}
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* Update viewport
|
||||
* ========================== */
|
||||
|
||||
/* Calculate screen viewport dimensions */
|
||||
if (L.debug_camera) {
|
||||
L.viewport_size = L.screen_size;
|
||||
L.viewport_screen_offset = V2(0, 0);
|
||||
} else {
|
||||
|
||||
/* Determine viewport size by camera & window dimensions */
|
||||
f32 aspect_ratio = 1.0;
|
||||
if (!v2_eq(active_camera->camera_size, V2(0, 0))) {
|
||||
aspect_ratio = active_camera->camera_size.x / active_camera->camera_size.y;
|
||||
}
|
||||
f32 width = L.screen_size.x;
|
||||
f32 height = L.screen_size.y;
|
||||
if (width / height > aspect_ratio) {
|
||||
width = height * aspect_ratio;
|
||||
} else {
|
||||
height = (f32)math_ceil(width / aspect_ratio);
|
||||
}
|
||||
L.viewport_size = V2(width, height);
|
||||
|
||||
/* Center viewport in window */
|
||||
f32 x = 0;
|
||||
f32 y = 0;
|
||||
x = math_round(L.screen_size.x / 2 - width / 2);
|
||||
y = math_round(L.screen_size.y / 2 - height / 2);
|
||||
L.viewport_screen_offset = V2(x, y);
|
||||
}
|
||||
|
||||
L.viewport_center = v2_mul(L.viewport_size, 0.5);
|
||||
L.viewport_cursor = v2_sub(L.screen_cursor, L.viewport_screen_offset);
|
||||
|
||||
/* ========================== *
|
||||
* Update view
|
||||
* ========================== */
|
||||
|
||||
if (L.debug_camera) {
|
||||
/* Pan view */
|
||||
if (L.bind_states[USER_BIND_KIND_PAN].is_held) {
|
||||
@ -602,13 +608,18 @@ INTERNAL void user_update(void)
|
||||
} else {
|
||||
struct v2 center = active_camera->world_xform.og;
|
||||
f32 rot = xform_get_rotation(active_camera->world_xform);
|
||||
f32 zoom = active_camera->camera_zoom;
|
||||
zoom = zoom > 0 ? zoom : 1;
|
||||
|
||||
/* Scale view into viewport based on camera size */
|
||||
struct v2 size = L.viewport_size;
|
||||
if (!v2_eq(active_camera->camera_size, V2(0, 0))) {
|
||||
size = v2_div_v2(size, active_camera->camera_size);
|
||||
}
|
||||
f32 scale = min_f32(size.x, size.y);
|
||||
|
||||
struct trs trs = TRS(
|
||||
.t = v2_sub(L.viewport_center, center),
|
||||
.r = rot,
|
||||
.s = v2_mul(V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT), zoom)
|
||||
.s = V2(scale, scale)
|
||||
);
|
||||
|
||||
struct v2 pivot = center;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user