viewport scaling by camera size
This commit is contained in:
parent
b53dfe93f8
commit
c6ca5c0c9a
@ -5,8 +5,9 @@
|
|||||||
* system. */
|
* system. */
|
||||||
#define RESOURCES_EMBEDDED !(DEVELOPER)
|
#define RESOURCES_EMBEDDED !(DEVELOPER)
|
||||||
|
|
||||||
//#define ASPECT_RATIO (16.0 / 9.0)
|
#define DEFAULT_CAMERA_WIDTH (6)
|
||||||
#define ASPECT_RATIO (4.0 / 3.0)
|
#define DEFAULT_CAMERA_ASPECT_RATIO (16.0 / 9.0)
|
||||||
|
|
||||||
#define PIXELS_PER_UNIT 256
|
#define PIXELS_PER_UNIT 256
|
||||||
|
|
||||||
#define GAME_FPS 50
|
#define GAME_FPS 50
|
||||||
|
|||||||
@ -95,7 +95,7 @@ struct entity {
|
|||||||
/* ENTITY_PROP_CAMERA */
|
/* ENTITY_PROP_CAMERA */
|
||||||
struct entity_handle camera_follow;
|
struct entity_handle camera_follow;
|
||||||
struct xform camera_target_xform; /* Calculated from 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 */
|
f32 camera_lerp; /* Rate at which camera xform approaches target xform */
|
||||||
u32 camera_lerp_gen;
|
u32 camera_lerp_gen;
|
||||||
u32 camera_applied_lerp_gen_plus_one; /* Calculated */
|
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);
|
||||||
entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE);
|
entity_enable_prop(e, ENTITY_PROP_CAMERA_ACTIVE);
|
||||||
e->camera_follow = player_ent->handle;
|
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 */
|
/* Sound ent */
|
||||||
@ -473,8 +476,12 @@ INTERNAL void game_update(void)
|
|||||||
ent->camera_target_xform.og = target_pos;
|
ent->camera_target_xform.og = target_pos;
|
||||||
#else
|
#else
|
||||||
/* "Look" style camera */
|
/* "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_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_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);
|
struct v2 camera_focus_pos = v2_add(follow->world_xform.og, camera_focus_dir);
|
||||||
ent->camera_target_xform.og = camera_focus_pos;
|
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);
|
arena_release(&buffer->index_arena);
|
||||||
|
|
||||||
/* FIXME: Clear GPU buffers */
|
/* 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);
|
struct v2 monitor_size = sys_window_get_monitor_size(window);
|
||||||
|
|
||||||
i32 width = 1280;
|
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 x = math_round(monitor_size.x / 2.f - width / 2);
|
||||||
i32 y = math_round(monitor_size.y / 2.f - height / 2);
|
i32 y = math_round(monitor_size.y / 2.f - height / 2);
|
||||||
|
|
||||||
|
|||||||
89
src/user.c
89
src/user.c
@ -38,7 +38,6 @@ GLOBAL struct {
|
|||||||
struct renderer_canvas *world_canvas;
|
struct renderer_canvas *world_canvas;
|
||||||
struct renderer_canvas *viewport_bg_canvas;
|
struct renderer_canvas *viewport_bg_canvas;
|
||||||
struct renderer_canvas *viewport_canvas;
|
struct renderer_canvas *viewport_canvas;
|
||||||
struct xform world_view_last_frame;
|
|
||||||
struct xform world_view;
|
struct xform world_view;
|
||||||
|
|
||||||
struct blend_tick *head_free_blend_tick;
|
struct blend_tick *head_free_blend_tick;
|
||||||
@ -342,33 +341,7 @@ INTERNAL void user_update(void)
|
|||||||
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
|
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
|
||||||
L.dt = max_f64(0.0, cur_time - L.time);
|
L.dt = max_f64(0.0, cur_time - L.time);
|
||||||
L.time += L.dt;
|
L.time += L.dt;
|
||||||
|
L.screen_size = sys_window_get_size(L.window);
|
||||||
/* 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
|
* 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->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->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);
|
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 */
|
/* Update mouse pos */
|
||||||
if (event->kind == SYS_EVENT_KIND_CURSOR_MOVE) {
|
if (event->kind == SYS_EVENT_KIND_CURSOR_MOVE) {
|
||||||
L.screen_cursor = event->cursor_position;
|
L.screen_cursor = event->cursor_position;
|
||||||
L.viewport_cursor = v2_sub(L.screen_cursor, L.viewport_screen_offset);;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update bind states */
|
/* 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) {
|
if (L.bind_states[USER_BIND_KIND_DEBUG_DRAW].num_presses > 0) {
|
||||||
L.debug_draw = !L.debug_draw;
|
L.debug_draw = !L.debug_draw;
|
||||||
}
|
}
|
||||||
@ -562,6 +528,46 @@ INTERNAL void user_update(void)
|
|||||||
L.debug_camera = !L.debug_camera;
|
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) {
|
if (L.debug_camera) {
|
||||||
/* Pan view */
|
/* Pan view */
|
||||||
if (L.bind_states[USER_BIND_KIND_PAN].is_held) {
|
if (L.bind_states[USER_BIND_KIND_PAN].is_held) {
|
||||||
@ -602,13 +608,18 @@ INTERNAL void user_update(void)
|
|||||||
} else {
|
} else {
|
||||||
struct v2 center = active_camera->world_xform.og;
|
struct v2 center = active_camera->world_xform.og;
|
||||||
f32 rot = xform_get_rotation(active_camera->world_xform);
|
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(
|
struct trs trs = TRS(
|
||||||
.t = v2_sub(L.viewport_center, center),
|
.t = v2_sub(L.viewport_center, center),
|
||||||
.r = rot,
|
.r = rot,
|
||||||
.s = v2_mul(V2(PIXELS_PER_UNIT, PIXELS_PER_UNIT), zoom)
|
.s = V2(scale, scale)
|
||||||
);
|
);
|
||||||
|
|
||||||
struct v2 pivot = center;
|
struct v2 pivot = center;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user