test_game.c (21338B)
1 #include "debug.h" 2 #include "test_game.h" 3 #include "camera.h" 4 #include "entity.h" 5 #include "orbit_util.h" 6 #include "engine.h" 7 #include "node.h" 8 #include "render.h" 9 #include "shader.h" 10 #include "quat.h" 11 #include "movement.h" 12 #include "gpu.h" 13 #include "util.h" 14 #include "terrain_collision.h" 15 #include "orbit_util.h" 16 #include "mat_util.h" 17 #include "procmesh.h" 18 19 static const float bias_matrix[] = { 20 0.5, 0.0, 0.0, 0.0, 21 0.0, 0.5, 0.0, 0.0, 22 0.0, 0.0, 0.5, 0.0, 23 0.5, 0.5, 0.5, 1.0 24 }; 25 26 #define CU_LENS(field, typ) { #field, offsetof(struct common_uniforms, field), DATA_ID_##typ } 27 static struct lens common_lenses[] = { 28 CU_LENS(fog_on, INT), 29 CU_LENS(sky_intensity, FLOAT), 30 CU_LENS(light_intensity, FLOAT), 31 CU_LENS(depth_mvp, MAT4), 32 CU_LENS(mvp, MAT4), 33 CU_LENS(model_view, MAT4), 34 CU_LENS(normal_matrix, MAT4), 35 CU_LENS(sun_color, VEC3), 36 CU_LENS(camera_position, VEC3P), 37 CU_LENS(light_dir, VEC3), 38 }; 39 #undef CU_LENS 40 41 struct lens *get_common_lenses() 42 { 43 return common_lenses; 44 } 45 46 int get_common_lenses_length() 47 { 48 return ARRAY_SIZE(common_lenses); 49 } 50 51 static void resize_fbos(struct entity *player, struct fbo *shadow_buffer, 52 float *m4_ortho, int width, int height) 53 { 54 if (shadow_buffer->handle) { 55 // TODO: remove once delete_fbo deletes attachments 56 glDeleteTextures(1, &shadow_buffer->attachments[1]); 57 glDeleteRenderbuffers(1, &shadow_buffer->attachments[0]); 58 delete_fbo(shadow_buffer); 59 } 60 61 // TODO: compute better bounds based 62 const float factor = 60.5; 63 64 struct model *model = get_model(&player->model_id); assert(model); 65 struct geometry *geom = get_geometry(&model->geom_id); assert(geom); 66 67 float left = geom->min[0] - factor; 68 float right = geom->max[0] + factor; 69 float bottom = geom->min[1] - factor; 70 float top = geom->max[1] + factor; 71 72 /* float left = -factor; */ 73 /* float right = factor; */ 74 /* float bottom = factor; */ 75 /* float top = -factor; */ 76 77 const float near = -50.0; 78 const float far = 50.0; 79 80 // default ortho screenspace projection 81 //mat4_ortho(left, right, bottom, top, near, far, m4_ortho); 82 83 create_fbo(shadow_buffer, width, height ); 84 //fbo_attach_renderbuffer(shadow_buffer, GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT); 85 86 //fbo_attach_color_texture(shadow_buffer); 87 fbo_attach_depth_texture(shadow_buffer); 88 89 check_fbo(shadow_buffer); 90 91 /* fbo_attach_texture(&res->shadow_buffer, GL_DEPTH_COMPONENT16, */ 92 /* GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); */ 93 } 94 95 96 static struct entity *get_player(struct test_game *res) { 97 struct entity *player = get_entity(&res->player_id); 98 assert(player); 99 return player; 100 } 101 102 static struct entity *get_terrain_entity(struct terrain *t) { 103 struct entity *ent = get_entity(&t->entity_id); 104 assert(ent); 105 return ent; 106 } 107 108 static void player_movement(struct engine *engine, struct entity *player) { 109 /* if (player->flags & ENT_ON_GROUND) */ 110 /* entity_movement(game, player); */ 111 struct node *node = get_node(&player->node_id); 112 movement(engine, node, 2.0); 113 } 114 115 static void camera_keep_above_ground(struct terrain *terrain, 116 struct node *camera) { 117 if (get_entity(&terrain->entity_id)->flags & ENT_INVISIBLE) 118 return; 119 float move[3]; 120 float *camworld = node_world(camera); 121 float pen = 0.0; 122 static const float penlim = 1.0; 123 struct tri *tri = collide_terrain(terrain, camworld, move, &pen); 124 125 if (!tri) 126 return; 127 128 if (pen < penlim) { 129 float dir[3], above[3]; 130 vec3_normalize(move, dir); 131 vec3_scale(dir, pen < 0 ? penlim : -penlim, above); 132 vec3_add(camworld, move, camworld); 133 vec3_add(camworld, above, camworld); 134 /* vec3_add(move, above, move); */ 135 /* vec3_add(camworld, move, camworld); */ 136 } 137 } 138 139 static void entity_movement(struct engine *engine, struct entity *ent) 140 { 141 static const float move_accel = 1.0f; 142 static const float max_speed = 10.0f; 143 struct node *node = get_node(&ent->node_id); 144 145 float vel[3]; 146 147 float amt = 10.0 * engine->dt; 148 149 if (engine->input.keystates[SDL_SCANCODE_W]) { 150 vec3_forward(ent->velocity, node->orientation, V3(0,amt,0), vel); 151 if (vec3_lengthsq(vel) <= max_speed*max_speed) 152 vec3_copy(vel, ent->velocity); 153 } 154 } 155 156 157 static void player_terrain_collision(struct terrain *terrain, struct node *node) { 158 // player movement 159 static vec3 last_pos[3] = {0}; 160 161 if (!vec3_approxeq(node->pos, last_pos)) { 162 float player_z = node->pos[2]; 163 164 float terrain_z = 165 terrain->fn(terrain, node->pos[0], node->pos[1]); 166 167 float inset = 168 min(0.0, player_z - terrain_z); 169 170 if (inset <= 0) 171 node_translate(node, V3(0.0, 0.0, -inset)); 172 } 173 174 } 175 176 // TODO: match based on some real concept of time 177 static void day_night_cycle(float time, struct test_game *res) { 178 float val = time * 0.0001; 179 float intensity = 1.0;//max(0.0, vec3_dot(res->light_dir, V3(0.0, 0.0, 1.0))); */ 180 struct entity *player = get_player(res); 181 struct node *pnode = get_node(&player->node_id); 182 assert(pnode); 183 struct node *suncam = get_node(&res->sun_camera_id); 184 assert(suncam); 185 struct common_uniforms *cvars = &res->common_vars; 186 187 float light_pos[3]; 188 189 float g = 0.6; 190 float b = 0.4; 191 cvars->sun_color[0] = 1.0; 192 cvars->sun_color[1] = g+intensity*(1.0-g); 193 cvars->sun_color[2] = b+intensity*(1.0-b); 194 195 /* res->sun_color[0] = 1.0; */ 196 /* res->sun_color[1] = 1.0; */ 197 /* res->sun_color[2] = 1.0; */ 198 199 /* vec3_scale(res->sun_color, res->light_intensity, gtmp); */ 200 201 /* float intensity = angle <= 0.5 */ 202 /* ? clamp(roots, darkest, 1.0) */ 203 /* : clamp(-roots * 0.4, darkest, 0.5); */ 204 205 cvars->light_intensity = intensity; 206 207 /* vec3_normalize(res->light_intensity, res->light_intensity); */ 208 209 cvars->light_dir[0] = 0.0; 210 /* res->light_dir[1] = sin(val); */ 211 /* res->light_dir[2] = cos(val) + 1.0; */ 212 cvars->light_dir[1] = 0.8; 213 cvars->light_dir[2] = 0.8; 214 215 vec3_normalize(cvars->light_dir, cvars->light_dir); 216 217 /* printf("intensity %f(%f) n %f light_dir %f %f\n", roots, intensity, */ 218 /* n, res->light_dir[1], res->light_dir[2]); */ 219 220 vec3_add(pnode->pos, cvars->light_dir, light_pos); 221 222 /* float target[3]; */ 223 /* float hh = player->model.geom.max[2] / 2.0; */ 224 /* vec3_copy(player->node.pos, target); */ 225 /* target[2] += 2.0; */ 226 227 look_at(light_pos, pnode->pos, V3(0, 0, 1.0), suncam->mat); 228 /* look_at(light_pos, player->node.pos, V3(0, 0, 1.0), res->sun_camera.mat); */ 229 } 230 231 static void player_update(struct engine *engine, struct test_game *game, struct entity *player) 232 { 233 struct orbit *camera = &game->orbit_camera; 234 struct node *node = get_node(&player->node_id); 235 struct node *cam_node = get_node(&game->camera_node_id); 236 assert(node); 237 assert(cam_node); 238 239 orbit_update_from_mouse(camera, &engine->input, 240 engine->user_settings.mouse_sens, 241 player, NULL, engine->dt); 242 243 camera_keep_above_ground(&game->terrain, cam_node); 244 245 // move player camera toward camera orientation 246 if (input_is_dragging(&engine->input, SDL_BUTTON_RIGHT)) { 247 float yaw = game->orbit_camera.coords.azimuth; 248 quat_axis_angle(V3(0.0, 0.0, 1.0), -yaw - RAD(90), node->orientation); 249 } 250 251 struct terrain *terrain = &game->terrain; 252 253 player_terrain_collision(terrain, node); 254 255 float move[3]; 256 float pos[3]; 257 float pen = 0.0; 258 vec3_copy(node_world(node), pos); 259 /* debug("node_world(player) %f %f %f\n", pos[0], pos[1], pos[2]); */ 260 struct tri *tri = collide_terrain(terrain, pos, move, &pen); 261 //struct tri *tri = NULL; 262 /* node_translate(node, move); */ 263 264 if (tri) { 265 if (vec3_eq(move, V3(0,0,0), 0.1)) { 266 player->flags |= ENT_ON_GROUND; 267 } 268 else if (pen < 0) { 269 node_translate(node, move); 270 /* vec3_all(player->velocity, 0); */ 271 vec3_scale(player->velocity, 0.1, player->velocity); 272 } 273 else { 274 player->flags &= ~ENT_ON_GROUND; 275 } 276 } 277 else { 278 static int tric = 0; 279 /* debug("%d no tri\n", tric++); */ 280 } 281 282 if (player->flags & ENT_ON_GROUND && 283 (was_key_pressed_this_frame(engine, SDL_SCANCODE_SPACE) /*|| 284 was_button_pressed_this_frame(engine, SDL_CONTROLLER_BUTTON_X)*/)) { 285 entity_jump(player, 2.0); 286 } 287 288 /* debug("player velocity %f %f %f\n", */ 289 /* player->velocity[0], */ 290 /* player->velocity[1], */ 291 /* player->velocity[2]); */ 292 293 // if (player->flags & ENT_AT_REST) 294 // vec3_scale(player->velocity, 0.00001, player->velocity); 295 296 node_translate(node, player->velocity); 297 node_recalc(node); 298 } 299 300 enum binding_structs { 301 COMMON_UNIFORMS, 302 CHESS_PIECE_UNIFORMS, 303 }; 304 305 static struct structure_binding uniform_bindings[] = { 306 [COMMON_UNIFORMS] = 307 { common_lenses, ARRAY_SIZE(common_lenses) }, 308 }; 309 310 void init_test_gl(struct test_game *game, struct gpu *gpu, int width, int height) 311 { 312 struct shader vertex, terrain_vertex, terrain_geom, fragment, fragment_smooth; 313 struct shader terrain_teval, terrain_tc; 314 float tmp_matrix[16]; 315 int ok = 0; 316 317 gpu->num_programs = NUM_TEST_GAME_PROGRAMS; 318 319 // Shaders 320 ok = make_shader(GL_VERTEX_SHADER, SHADER("vertex-color.glsl"), 321 &vertex); 322 rtassert(ok, "vertex-color shader"); 323 324 ok = make_shader(GL_VERTEX_SHADER, SHADER("terrain.v.glsl"), &terrain_vertex); 325 rtassert(ok, "terrain vertex shader"); 326 check_gl(); 327 328 ok = make_shader(GL_FRAGMENT_SHADER, SHADER("main.f.glsl"), &fragment); 329 rtassert(ok, "default fragment shader"); 330 check_gl(); 331 332 // camera 333 mat4_perspective(90 /* fov */, 334 (float)width / height, 335 1, 336 5000, 337 game->proj_persp); 338 339 struct gpu_program *programs = gpu->programs; 340 341 ok = make_program("terrain", &terrain_vertex, &fragment, 342 &programs[TERRAIN_PROGRAM], 343 uniform_bindings, 344 ARRAY_SIZE(uniform_bindings)); 345 rtassert(ok, "terrain program"); 346 check_gl(); 347 348 ok = make_program("vertex-color", &vertex, &fragment, 349 &programs[DEFAULT_PROGRAM], 350 uniform_bindings, 351 ARRAY_SIZE(uniform_bindings)); 352 rtassert(ok, "vertex-color program"); 353 check_gl(); 354 } 355 356 357 // TODO: add uniforms automatically? 358 359 static void render_test_game(struct gpu *gpu, struct test_game *game, struct render_config *config) { 360 float gtmp[3]; 361 u32 num_entities; 362 363 struct common_uniforms *cvars = &game->common_vars; 364 365 cvars->sky_intensity = clamp(cvars->light_intensity, 0.2, 1.0); 366 vec3_scale(cvars->sun_color, cvars->sky_intensity, gtmp); 367 368 glEnable(GL_DEPTH_TEST); 369 370 glClearColor( gtmp[0], gtmp[1], gtmp[2], 1.0 ); //clear background screen to black 371 /* glClearColor( 0.5294f * adjust, 0.8078f * adjust, 0.9216f * adjust, 1.0f ); //clear background screen to black */ 372 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 373 374 check_gl(); 375 376 static float id[MAT4_ELEMS] = { 0 }; 377 static float view[MAT4_ELEMS] = { 0 }; 378 static float view_proj[MAT4_ELEMS] = { 0 }; 379 static float normal_matrix[MAT4_ELEMS] = { 0 }; 380 381 mat4_id(id); 382 mat4_id(cvars->model_view); 383 384 mat4 *projection = config->projection; 385 386 struct node *camera_node = get_node(&config->camera); 387 assert(camera_node); 388 389 const mat4 *camera = camera_node->mat; 390 391 struct entity *entities = 392 get_all_entities(&num_entities, NULL); 393 394 struct gpu_program *program = NULL; 395 396 mat4_inverse((float*)camera, view); 397 mat4_multiply(projection, view, view_proj); 398 399 if (config->is_depth_pass) { 400 glDisable(GL_CULL_FACE); 401 mat4_multiply(bias_matrix, view_proj, config->depth_vp); 402 } 403 else { 404 glCullFace(GL_BACK); 405 } 406 407 mat4_inverse((float *)camera, view); 408 mat4_multiply(projection, view, view_proj); 409 410 struct model *skybox_model = get_model(&game->skybox.model_id); 411 assert(skybox_model); 412 413 glBindTexture(GL_TEXTURE_CUBE_MAP, skybox_model->texture); 414 check_gl(); 415 416 cvars->camera_position = (float*)&camera[M_X]; 417 418 for (u32 i = 0; i < num_entities; ++i) { 419 struct entity *entity = &entities[i]; 420 struct model *model = get_model(&entity->model_id); 421 assert(model); 422 struct node *node = get_node(&entity->node_id); 423 assert(node); 424 425 if (entity->flags & ENT_INVISIBLE) 426 continue; 427 428 if (config->is_depth_pass && !(entity->flags & ENT_CASTS_SHADOWS)) 429 continue; 430 431 program = &gpu->programs[model->shader]; 432 433 glUseProgram(program->handle); 434 check_gl(); 435 436 mat4_multiply(view_proj, node->mat, cvars->mvp); 437 mat4_copy(node->mat, cvars->model_view); 438 mat4_multiply(config->depth_vp, cvars->model_view, cvars->depth_mvp); 439 440 void *shader_data[] = { 441 [COMMON_UNIFORMS] = cvars, 442 [CHESS_PIECE_UNIFORMS] = entity->data, 443 }; 444 445 bind_uniforms(program, shader_data, ARRAY_SIZE(shader_data)); 446 check_gl(); 447 448 /* 449 recalc_normals(program->uniforms[UNIFORM_NORMAL_MATRIX].location, 450 model_view, normal_matrix); 451 452 check_gl(); 453 */ 454 455 struct geometry *geo = get_geometry(&model->geom_id); 456 /* debug("geo node %s\n", node->label); */ 457 assert(geo); 458 render_geometry(geo, program); 459 check_gl(); 460 } 461 462 if (gpu->wireframe) { 463 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); 464 } 465 else { 466 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); 467 } 468 469 if (!config->is_depth_pass) { 470 mat4_inverse((float*)camera, view); 471 mat4_remove_translations(view); 472 mat4_multiply(projection, view, view_proj); 473 474 render_skybox(&game->skybox, view_proj); 475 } 476 477 if (config->draw_ui) 478 render_ui(&game->ui, view); 479 480 //player 481 // y tho 482 483 // terrain 484 485 /* glUniformMatrix4fv(res->uniforms.mvp, 1, 0, mvp); */ 486 /* glUniformMatrix4fv(res->uniforms.model_view, 1, 0, id); */ 487 /* glUniformMatrix4fv(res->uniforms.world, 1, 0, id); */ 488 /* glUniformMatrix4fv(res->uniforms.normal_matrix, 1, 0, id); */ 489 /* recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); */ 490 /* render_geom(res, geom, GL_TRIANGLES); */ 491 /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */ 492 /* render_geom(res, geom, GL_TRIANGLES); */ 493 } 494 495 496 void update_test_game (struct engine *engine, struct test_game *game) { 497 static int toggle_fog = 0; 498 static int needs_terrain_update = 0; 499 //struct terrain *terrain = &game->terrain; 500 struct node *root = get_node(&game->root_id); 501 struct entity *player = get_player(game); 502 struct node *pnode = get_node(&player->node_id); 503 struct node *cam_node = get_node(&game->camera_node_id); 504 struct common_uniforms *cvars = &game->common_vars; 505 506 assert(pnode); 507 assert(cam_node); 508 509 float *time = &game->time; 510 float *light = cvars->light_dir; 511 512 gravity(player, engine->dt); 513 514 if (needs_terrain_update) { 515 /* update_terrain(terrain); */ 516 needs_terrain_update = 0; 517 } 518 519 /* spherical_dir(game->test_resources.camera.coords, camera_dir); */ 520 /* vec3_scale(camera_dir, -1, camera_dir); */ 521 522 if (engine->input.modifiers & KMOD_ALT && 523 ideq(&game->camera_node_id, &game->free_camera_id)) 524 { 525 struct node *freecam_node = get_node(&game->free_camera_id); 526 assert(freecam_node); 527 assert(streq(freecam_node->label, "freecam")); 528 movement(engine, freecam_node, 1.0); 529 } else { 530 player_movement(engine, player); 531 } 532 533 assert(root->parent_id.id.generation == 0); 534 535 player_update(engine, game, player); 536 537 #ifdef DEBUG 538 if (was_key_pressed_this_frame(engine, SDL_SCANCODE_R)) { 539 try_reload_shaders(&engine->gpu); 540 } 541 #endif 542 543 if (was_key_pressed_this_frame(engine, SDL_SCANCODE_F5)) { 544 engine->gpu.wireframe ^= 1; 545 } 546 547 if (was_key_pressed_this_frame(engine, SDL_SCANCODE_C)) { 548 printf("light_dir %f %f %f\n", light[0], light[1], light[2]); 549 } 550 551 if (was_key_pressed_this_frame(engine, SDL_SCANCODE_F)) { 552 toggle_fog = 1; 553 } 554 555 if (was_key_pressed_this_frame(engine, SDL_SCANCODE_EQUALS)) { 556 if (!ideq(&game->camera_node_id, &game->free_camera_id)) { 557 debug("switching to freecam\n"); 558 game->camera_node_id = game->free_camera_id; 559 } 560 else { 561 debug("switching to orbitcam\n"); 562 game->camera_node_id = game->orbit_camera.node_id; 563 } 564 } 565 566 if (toggle_fog) { 567 cvars->fog_on ^= 1; 568 toggle_fog = 0; 569 } 570 571 *time = SDL_GetTicks(); 572 573 day_night_cycle(*time, game); 574 575 node_recalc(root); 576 } 577 578 void test_game_frame(struct engine *engine, struct test_game *game) 579 { 580 static float depth_vp[MAT4_ELEMS]; 581 mat4_id(depth_vp); 582 583 struct render_config fbo_render_config = { 584 .draw_ui = 0, 585 .is_depth_pass = 1, 586 .camera = game->sun_camera_id, 587 .projection = game->proj_ortho, 588 .depth_vp = depth_vp 589 }; 590 591 struct render_config default_config = { 592 .draw_ui = 0, 593 .is_depth_pass = 0, 594 .camera = game->camera_node_id, 595 .projection = game->proj_persp, 596 .depth_vp = depth_vp 597 }; 598 599 struct entity *player = get_entity(&game->player_id); 600 if (engine->input.resized_height) { 601 mat4_perspective(60 /* fov */, 602 (float)engine->width / (float)engine->height, 0.1, 603 10000.0, game->proj_persp); 604 605 resize_fbos(player, &game->shadow_buffer, game->proj_ortho, 606 engine->width, engine->height); 607 } 608 609 update_test_game(engine, game); 610 611 //struct fbo *fbo = &game->shadow_buffer; 612 //check_fbo(fbo); 613 //bind_fbo(fbo); 614 /* glDrawBuffer(GL_NONE); */ 615 616 //render_test_game(&engine->gpu, game, &fbo_render_config); 617 //unbind_fbo(&game->shadow_buffer); 618 render_test_game(&engine->gpu, game, &default_config); 619 } 620 621 void init_test_game(struct engine *engine, struct test_game *game) 622 { 623 memset(game, 0, sizeof(*game)); 624 struct terrain *terrain = &game->terrain; 625 struct entity *player; 626 struct model *model; 627 struct common_uniforms *cvars = &game->common_vars; 628 629 init_test_gl(game, &engine->gpu, engine->width, engine->height); 630 631 init_id(&game->root_id); 632 init_id(&game->sun_camera_id); 633 init_id(&game->free_camera_id); 634 635 struct node *root = new_node(&game->root_id); 636 struct node *sun_camera = new_node(&game->sun_camera_id); 637 638 assert(root->parent_id.id.generation == 0); 639 assert(root); 640 assert(sun_camera); 641 642 const double size = 4000.0; 643 //double scale = 0.03; 644 double scale = 0.03; 645 646 create_skybox(&game->skybox, &engine->gpu.programs[SKYBOX_PROGRAM]); 647 create_ui(&game->ui, engine->width, engine->height, &engine->gpu.programs[UI_PROGRAM]); 648 649 terrain->settings = (struct perlin_settings){ 650 .depth = 1, 651 .freq = scale * 0.08, 652 .o1 = 2.0, .o1s = 0.5, 653 .o2 = 4.0, .o2s = 0.25, 654 .amplitude = 70.0, 655 .ox = 0, 656 .oy = 0, 657 .exp = 5.3, 658 .scale = scale 659 }; 660 661 init_terrain(terrain, size); 662 663 /* terrain->samples = load_samples(&seed, &terrain->n_samples); */ 664 terrain->n_samples = 0; 665 create_terrain(terrain, size, engine->seed); 666 //load_terrain(terrain); 667 /* update_terrain(terrain, terrain->cell_size); */ 668 /* get_entity(&terrain->entity_id)->flags |= ENT_INVISIBLE; */ 669 670 /* node_scale(&game->skybox.node, size/4.0); */ 671 672 mat4_id(cvars->mvp); 673 674 cvars->light_intensity = 0.8; 675 676 cvars->light_dir[0] = 0.8; 677 cvars->light_dir[1] = 0.8; 678 cvars->light_dir[2] = 0.8; 679 680 cvars->sun_color[0] = 0.5; 681 cvars->sun_color[1] = 0.6; 682 cvars->sun_color[2] = 0.7; 683 684 cvars->fog_on = 0; 685 //cvars->diffuse_on = 0; 686 687 node_init(root); 688 node_init(sun_camera); 689 new_orbit(&game->orbit_camera); 690 691 node_set_label(root, "root"); 692 693 // ENTITIES 694 695 // player entity 696 init_id(&game->player_id); 697 player = new_entity(&game->player_id); 698 player->flags |= ENT_CASTS_SHADOWS; 699 struct node *pnode = get_node(&player->node_id); 700 assert(pnode); 701 702 player->model_id = get_model_by_name("pirate_officer", NULL); 703 assert(!is_null_id(&player->model_id)); 704 705 706 node_set_label(pnode, "player"); 707 /* node_rotate(pnode, V3(-5.0,0,0)); */ 708 node_attach(&player->node_id, &game->root_id); 709 assert(ideq(&pnode->parent_id, &game->root_id)); 710 711 node_translate(pnode, V3(terrain->size/2.,terrain->size/2.,0.0)); 712 713 // orbit camera 714 game->orbit_camera.coords.azimuth = -quat_yaw(pnode->orientation) - RAD(90.0); 715 game->orbit_camera.coords.inclination = RAD(60); 716 game->orbit_camera.coords.radius = 5.0; 717 game->camera_node_id = game->orbit_camera.node_id; 718 719 // free camera 720 struct node *freecam = new_node(&game->free_camera_id); 721 node_set_label(freecam, "freecam"); 722 node_attach(&game->free_camera_id, &player->node_id); 723 quat_axis_angle(V3(1,0,0), -45, freecam->orientation); 724 node_rotate(freecam, V3(100, 0, 0)); 725 node_translate(freecam, V3(0,-40,20)); 726 727 // FBO STUFF 728 init_fbo(&game->shadow_buffer); 729 resize_fbos(player, &game->shadow_buffer, game->proj_ortho, engine->width, engine->height); 730 // FBO STUFF END 731 732 // TEXTURES 733 // END TEXTURES 734 } 735 736 void default_scene(struct test_game *game) { 737 struct terrain *terrain = &game->terrain; 738 struct entity *terrain_ent = get_terrain_entity(terrain); 739 struct entity *player = get_player(game); 740 741 // show terrain 742 terrain_ent->flags &= ~ENT_INVISIBLE; 743 744 // show player 745 player->flags &= ~ENT_INVISIBLE; 746 747 struct entity *tower = new_entity(NULL); 748 struct node *tnode = get_node(&tower->node_id); 749 struct node *pnode = get_node(&player->node_id); 750 751 assert(tnode); 752 tower->model_id = get_model_by_name("tower", NULL); 753 node_set_label(tnode, "tower"); 754 node_attach(&tower->node_id, &player->node_id); 755 node_translate(tnode, V3(0.0, 50.0, 0.0)); 756 node_recalc(tnode); 757 float z = terrain->fn(terrain, tnode->mat[M_X], tnode->mat[M_Y]); 758 /* node_detach(tnode, pnode); */ 759 tnode->mat[M_Z] = z; 760 } 761 762 763 764 void entity_test_scene(struct terrain *terrain) 765 { 766 struct model_id rock_model; 767 init_id(&rock_model); 768 769 /* model_id rock_model = get_static_model(model_tower, NULL); */ 770 struct model *pmodel = new_model(&rock_model, "procrock"); assert(pmodel); 771 struct geometry *geom = get_geometry(&pmodel->geom_id); assert(geom); 772 proc_sphere(geom); 773 774 for (int i = 0; i < 200; i++) { 775 struct entity *ent = new_entity(NULL); 776 struct node *node = get_node(&ent->node_id); 777 778 ent->model_id = rock_model; 779 780 double x = rand_0to1() * terrain->size; 781 double y = rand_0to1() * terrain->size; 782 double z = terrain->fn(terrain, x, y); 783 784 node_scale(node, pow(15.0, rand_0to1())); 785 node_rotate(node, V3(rand_0to1(),rand_0to1(),rand_0to1())); 786 node_translate(node, V3(x, y, z)); 787 node_set_label(node, "rock"); 788 789 node_recalc(node); 790 } 791 792 } 793 794 void pbr_scene(struct test_game *game) 795 { 796 struct entity *ent = new_entity(NULL); 797 struct node *node = get_node(&ent->node_id); assert(node); 798 struct entity *player = get_player(game); 799 800 ent->model_id = get_model_by_name("icosphere", NULL); 801 node_set_label(node, "sphere"); 802 }