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; }