Пример #1
0
ENTRYPOINT void
draw_camera (ModeInfo *mi)
{
  camera_configuration *bp = &bps[MI_SCREEN(mi)];
  Display *dpy = MI_DISPLAY(mi);
  Window window = MI_WINDOW(mi);
  GLfloat camera_size;
  int i;

  if (!bp->glx_context)
    return;

  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix ();

# ifdef HAVE_MOBILE
  glRotatef (current_device_rotation(), 0, 0, 1);  /* right side up */
# endif

  gltrackball_rotate (bp->user_trackball);

# ifdef HAVE_MOBILE
  {
    GLfloat s = 0.6;
    glScalef (s, s, s);
  }
# endif

# ifdef DEBUG
  if (debug_p)
    {
      GLfloat s = 0.2;
      glScalef (s, s, s);
      glRotatef (30, 0, 1, 0);
      glRotatef (15, 1, 0, 0);
      glTranslatef (0, 0, -80);
    }
# endif

  mi->polygon_count = 0;

  camera_size = 5;

  if (MI_COUNT(mi) <= 2)    /* re-frame the scene a little bit */
    glTranslatef (0, -1, 7);
  if (MI_COUNT(mi) >= 20)
    glTranslatef (0, -1.5, -5);
  if (MI_COUNT(mi) >= 40)
    glTranslatef (0, 2, -15);

  glScalef (camera_size, camera_size, camera_size);

  /* +Z is toward sky; +X is toward the right along the back wall;
     +Y is toward the viewer. */
  glRotatef (-90, 1, 0, 0);
  glScalef (1, -1, 1);

  glPushMatrix();
  glScalef (1/camera_size, 1/camera_size, 1/camera_size);
  glTranslatef (0, -2.38, -8);  /* Move the ground down and back */
  glCallList (bp->dlists[GROUND]);
  mi->polygon_count += ground->points;

  glPopMatrix();

  {
    pedestrian *p, *p2;
    for (p = bp->pedestrians, p2 = p ? p->next : 0;
         p;
         p = p2, p2 = p2 ? p2->next : 0)
      {
        mi->polygon_count += draw_pedestrian (mi, p);
        tick_pedestrian (mi, p);  /* might free p */
      }

    if (!bp->pedestrians || !(random() % MAX (1, (int) (200 / speed_arg))))
      add_pedestrian (mi);
  }

  for (i = 0; i < bp->ncameras; i++)
    {
      camera *c = &bp->cameras[i];
      mi->polygon_count += draw_camera_1 (mi, c);
      tick_camera (mi, c);
    }

  for (i = 0; i < bp->ncameras; i++)
    {
      camera *c = &bp->cameras[i];
      if (c->state == ZOT)  /* Do this last, for alpha blending */
        mi->polygon_count += draw_ray (mi, c);
    }

  glPopMatrix ();

  if (mi->fps_p) do_fps (mi);
  glFinish();

  glXSwapBuffers(dpy, window);
}
Пример #2
0
Файл: gx.c Проект: LWSS/gx
void tick_game(struct GameMemory *memory, struct Input *input, uint32 screen_width, uint32 screen_height, float dt)
{
    struct GameState *game_state = (struct GameState *)memory->game_memory;
    struct RenderBuffer *render_buffer = (struct RenderBuffer *)memory->render_memory;

    clear_render_buffer(render_buffer);

    for (uint32 i = 0; i < game_state->visibility_graph.vertex_count; ++i)
    {
        vec2 vertex = game_state->visibility_graph.vertices[i];
        draw_world_quad_buffered(render_buffer, vertex, vec2_scalar(0.1f), vec4_zero(), vec3_new(0, 1, 1));
    }

    for (uint32 i = 0; i < game_state->visibility_graph.edge_count; ++i)
    {
        uint32 *edge = &game_state->visibility_graph.edges[i][0];

        vec2 p0 = game_state->visibility_graph.vertices[edge[0]];
        vec2 p1 = game_state->visibility_graph.vertices[edge[1]];

        draw_world_line_buffered(render_buffer, p0, p1, vec3_new(1, 1, 0));
    }

    if (mouse_down(MOUSE_LEFT, input))
    {
        struct AABB box = calc_mouse_selection_box(input, MOUSE_LEFT);

        vec2 size = vec2_sub(box.max, box.min);
        vec2 bottom_left  = vec2_new(box.min.x, box.max.y);
        vec2 bottom_right = vec2_new(box.max.x, box.max.y);
        vec2 top_left     = vec2_new(box.min.x, box.min.y);
        vec2 top_right    = vec2_new(box.max.x, box.min.y);

        const uint32 outline_thickness = 1;

        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, bottom_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_right, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
    }

    if (mouse_released(MOUSE_LEFT, input))
    {
        // Clear previous selection.
        game_state->selected_ship_count = 0;

        struct AABB screen_selection_box = calc_mouse_selection_box(input, MOUSE_LEFT);

        // Because screen space y-values are inverted, these two results have conflicting
        // y-values, i.e. screen_to_world_min.y is actually the maximum y. These values
        // are then properly min/maxed and stored correctly in world_selection_box.
        vec2 screen_to_world_min = screen_to_world_coords(screen_selection_box.min, &game_state->camera, screen_width, screen_height);
        vec2 screen_to_world_max = screen_to_world_coords(screen_selection_box.max, &game_state->camera, screen_width, screen_height);

        struct AABB world_selection_box;
        world_selection_box.min = min_vec2(screen_to_world_min, screen_to_world_max);
        world_selection_box.max = max_vec2(screen_to_world_min, screen_to_world_max);

        // Add colliding ships to the selection list.
        // TODO: optimize, spatial grid hash?
        for (uint32 i = 0; i < game_state->ship_count; ++i)
        {
            struct Ship *ship = &game_state->ships[i];
            struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size);

            vec2 center = vec2_div(vec2_add(ship_aabb.min, ship_aabb.max), 2.0f);

            if (aabb_aabb_intersection(world_selection_box, ship_aabb))
                game_state->selected_ships[game_state->selected_ship_count++] = ship->id;
        }

        if (game_state->selected_ship_count > 0)
            fprintf(stderr, "selected %u ships\n", game_state->selected_ship_count);
    }

    if (mouse_down(MOUSE_RIGHT, input))
    {
        vec2 target_position = screen_to_world_coords(input->mouse_position, &game_state->camera, screen_width, screen_height);

        for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
        {
            uint32 id = game_state->selected_ships[i];
            struct Ship *ship = get_ship_by_id(game_state, id);

            ship->target_position = target_position;
            ship->move_order = true;
        }
    }

    // Outline selected ships.
    for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
    {
        uint32 id = game_state->selected_ships[i];
        struct Ship *ship = get_ship_by_id(game_state, id);

        draw_world_quad_buffered(render_buffer, ship->position, vec2_mul(ship->size, 1.1f), vec4_zero(), vec3_new(0, 1, 0));

        if (ship->move_order)
            draw_world_quad_buffered(render_buffer, ship->target_position, vec2_new(0.5f, 0.5f), vec4_zero(), vec3_new(0, 1, 0));
    }

    // Handle move orders.
    for (uint32 i = 0; i < game_state->ship_count; ++i)
    {
        struct Ship *ship = &game_state->ships[i];
        if (ship->move_order)
        {
            vec2 direction = vec2_zero();
            /*
            if (vec2_length2(direction) < FLOAT_EPSILON)
                direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
                */
            ship->move_velocity = vec2_mul(direction, 2.0f);

            /*
            vec2 direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
            ship->move_velocity = vec2_mul(direction, 2.0f);
            */

            if (vec2_distance2(ship->position, ship->target_position) < 0.1f)
            {
                ship->move_velocity = vec2_zero();
                ship->move_order = false;
            }
        }
    }

    tick_camera(input, &game_state->camera, dt);

    tick_combat(game_state, dt);
    tick_physics(game_state, dt);
}