1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
void init(prge_context_t *ctx, game_context_t *gctx)
{
gctx->camera = (camera_t){
.position = (v3){3.0f, 1.5f, 3.0f},
.fov = 90.0f,
.near = 0.1f,
.far = 1000.0f,
.angles = {20.0f, -45.0f, 0.0f}
};
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/data/shaders", ctx->dir);
gctx->mesh_shader = load_gl_shader(path, "mesh.vert", 0, "mesh.frag");
gctx->ui_shader = load_gl_shader(path, "ui.vert", 0, "ui.frag");
gctx->grid_shader = load_gl_shader(path, "grid.vert", 0, "grid.frag");
gctx->texture = prge_load_texture(ctx, "data/textures/grid.png", 1);
mesh_t *quad = push_arena(&ctx->arena, sizeof(mesh_t));
quad[0] = gen_quad_mesh(&ctx->arena, DEFAULT_TRANSFORM, 100.0f, 100.0f);
add_mesh_texture(quad, gctx->texture);
model_t grid_model = {DEFAULT_TRANSFORM, 1, quad};
grid_model.transform.rotation.x = -90.0f;
entity_t grid = {ENTITY_ALPHA, grid_model, V3_ZERO, V3_ZERO, BBOX_ZERO};
add_entity(grid, &ctx->entities);
model_t cube = prge_load_model(ctx, DEFAULT_TRANSFORM, "data/models/cube.obj");
add_mesh_texture(&cube.meshes[0], gctx->texture);
entity_t player = {ENTITY_COLLIDE, cube, {0.0f, 2.0f, 0.0f}, V3_ZERO, BBOX_UNIT};
gctx->player_id = add_entity(player, &ctx->entities);
entity_t floor = {ENTITY_COLLIDE, cube, V3_ZERO, V3_ZERO, BBOX_UNIT};
gctx->floor_id = add_entity(floor, &ctx->entities);
gctx->hurt_id = prge_load_sound_vorbis(ctx, "data/sounds/hurt.ogg");
}
void update_camera_first_person(game_context_t *gctx, input_t *input, float speed, float sens)
{
v3 r, u, f;
camera_get_vecs(gctx->camera, &r, &u, &f);
v3 ddp = V3_ZERO;
if (is_key_down(input->move_forward))
ddp = v3_add(ddp, v3_inv(f));
if (is_key_down(input->move_backward))
ddp = v3_add(ddp, f);
if (is_key_down(input->move_right))
ddp = v3_add(ddp, r);
if (is_key_down(input->move_left))
ddp = v3_add(ddp, v3_inv(r));
if (is_key_down(input->move_up))
ddp = v3_add(ddp, u);
if (is_key_down(input->move_down))
ddp = v3_add(ddp, v3_inv(u));
ddp = v3_norm(ddp);
gctx->camera.position = v3_add(gctx->camera.position, gctx->camera_dp);
gctx->camera_dp = v3_scalef(v3_add(gctx->camera_dp, v3_scalef(ddp, input->dt*speed)), 0.8f);
if (input->mouse.capture) {
gctx->camera.angles.y += input->mouse.offset.x*sens;
gctx->camera.angles.x += input->mouse.offset.y*sens;
if (gctx->camera.angles.x > 89.0f)
gctx->camera.angles.x = 89.0f;
if (gctx->camera.angles.x < -89.0f)
gctx->camera.angles.x = -89.0f;
}
}
void update_and_render(prge_context_t *ctx, game_context_t *gctx)
{
/* NOTE(pryazha): Update */
if (is_key_pressed(ctx->input.exit)) {
if (ctx->input.mouse.capture) {
ctx->input.mouse.capture = 0;
} else {
ctx->should_close = 1;
}
}
float speed = 1.0f, sens = 0.05f;
update_camera_first_person(gctx, &ctx->input, speed, sens);
/* TODO(pryazha): Update physics */
entity_t *player = get_entity(ctx->entities, gctx->player_id);
entity_t *floor = get_entity(ctx->entities, gctx->floor_id);
entity_t new = move_entity(*player, V3_UP, ctx->input.dt);
v3 color = {1.0f, 0.0f, 0.0f};
if (!check_collision(player, floor)) {
*player = new;
color = V3_ONE;
}
/* NOTE(pryazha): Render */
v3 bgcolor = {0.15f, 0.15f, 0.15f};
clear_window(bgcolor);
begin3d(ctx->window, gctx->mesh_shader, gctx->camera);
shader_set_v3(gctx->mesh_shader, "color", color);
draw_entities(ctx->entities, gctx->mesh_shader);
end3d();
begin3d_alpha(ctx->window, gctx->grid_shader, gctx->camera);
draw_entities_alpha(ctx->entities, gctx->grid_shader);
end3d_alpha();
int count = 2;
float width = (float)ctx->window.width*0.25f;
float height = (float)ctx->window.height*0.05f;
v2 start = {10, (float)ctx->window.height - height - 10};
v2 end = {start.x + width, start.y + height};
rect_t ui_rect = {start, end};
float padding = 5.0f;
ui_t ui = beginui(ctx->window, ctx->input, gctx->ui_shader,
ui_rect, &ctx->frame_arena, padding);
float button_width = width/count - 2.0f*padding;
float button_height = height - 2.0f*padding;
if (button(&ui, "capture mouse", button_width, button_height))
ctx->input.mouse.capture = 1;
if (button(&ui, "hurt sound", button_width, button_height))
prge_play_sound(ctx, gctx->hurt_id);
endui();
gctx->time += ctx->input.dt;
}
|