Games-Construder

 view release on metacpan or  search on metacpan

lib/Games/Construder/Client/Frontend.pm  view on Meta::CPAN

      width  => $WIDTH,
      height => $HEIGHT,
      d      => $DEPTH,
      gl     => 1,
      resizeable => 1
   );

   #d# my $init = SDL::Mixer::init (SDL::Mixer::MIX_INIT_OGG);
   #d# unless ($init & SDL::Mixer::MIX_INIT_OGG) {
   #d#    die "Couldn't initialize SDL Mixer for OGG!\n";
   #d# }

   #d# SDL::Mixer::open_audio( 44100, SDL::Mixer::AUDIO_S16SYS, 2, 4096 );
   #d# SDL::Mixer::Music::volume_music ($self->{res}->{config}->{volume_music});

   $self->set_ambient_light ($self->{res}->{config}->{ambient_light});

   SDL::Events::enable_unicode (1);
   $self->{sdl_event} = SDL::Event->new;
   SDL::Video::GL_set_attribute (SDL::Constants::SDL_GL_SWAP_CONTROL, 1);
   SDL::Video::GL_set_attribute (SDL::Constants::SDL_GL_DOUBLEBUFFER, 1);

   $self->init_gl;
}

sub init_gl {
   my ($self) = @_;

   glDepthFunc(GL_LESS);
   glEnable (GL_DEPTH_TEST);
   glDisable (GL_DITHER);

   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glEnable (GL_BLEND);
   glEnable (GL_CULL_FACE);
   glCullFace (GL_BACK);

   glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
   glEnable (GL_TEXTURE_2D);
   glEnable (GL_FOG);
   glClearDepth (1.0);
   glShadeModel (GL_FLAT);

   glFogi (GL_FOG_MODE, GL_LINEAR);
   glFogf (GL_FOG_DENSITY, 0.45);
   glHint (GL_FOG_HINT, GL_FASTEST);

   $self->visibility_radius ($PL_VIS_RAD);
   $self->update_fog;

   glViewport (0, 0, $WIDTH, $HEIGHT);
}

sub fog {
   my ($self) = @_;
   $self->{res}->{config}->{fog} eq ''
      ? $FOG_DEFAULT
      : $self->{res}->{config}->{fog}
}

sub update_fog {
   my ($self) = @_;
   my $fog = $FOGS{$self->fog ()} || $FOGS{$FOG_DEFAULT};
   glClearColor (@$fog);
   glFogfv_p (GL_FOG_COLOR, @$fog);
}

#  0 front  1 top    2 back   3 left   4 right  5 bottom
my @indices  = (
   qw/ 0 1 2 3 /, # 0 front
   qw/ 1 5 6 2 /, # 1 top
   qw/ 7 6 5 4 /, # 2 back
   qw/ 4 5 1 0 /, # 3 left
   qw/ 3 2 6 7 /, # 4 right
   qw/ 3 7 4 0 /, # 5 bottom
);

my @vertices = (
   [ 0,  0,  0 ],
   [ 0,  1,  0 ],
   [ 1,  1,  0 ],
   [ 1,  0,  0 ],

   [ 0,  0,  1 ],
   [ 0,  1,  1 ],
   [ 1,  1,  1 ],
   [ 1,  0,  1 ],
);

sub _render_quad {
   my ($pos, $scale) = @_;

   $scale ||= 1;

   for my $face (0..5) {
      for my $vertex (0..3) {
         my $index  = $indices[4 * $face + $vertex];
         my $coords = $vertices[$index];

         glVertex3f (
            ($coords->[0] * $scale) + $pos->[0],
            ($coords->[1] * $scale) + $pos->[1],
            ($coords->[2] * $scale) + $pos->[2]
         );
      }
   }
}

sub _render_highlight {
   my ($pos, $color, $rad) = @_;

   $rad ||= 0.08;
   $pos = vsubd ($pos, $rad, $rad, $rad);
   glPushMatrix;
   glBindTexture (GL_TEXTURE_2D, 0);
   glColor4f (@$color);
   glTranslatef (@$pos);
   glScalef (1 + 2*$rad, 1 + 2*$rad, 1+2*$rad);
   glBegin (GL_QUADS);
   _render_quad ([0, 0, 0]);
   glEnd;

lib/Games/Construder/Client/Frontend.pm  view on Meta::CPAN

   } elsif ($name eq 'f') {
      $self->change_look_lock (not $self->{look_lock});
   } elsif ($name eq 'left ctrl') {
      $self->{air_select_mode} = 1;
   } elsif ($name eq 'left shift') {
      $self->{movement}->{speed} = 1;
   } elsif ($name eq 'w') {
      $self->{movement}->{forward} =
         $self->{movement}->{backward} + 1;
   } elsif ($name eq 's') {
      $self->{movement}->{backward} =
         $self->{movement}->{forward} + 1;
   } elsif ($name eq 'a') {
      $self->{movement}->{left} =
         $self->{movement}->{right} + 1;
   } elsif ($name eq 'd') {
      $self->{movement}->{right} =
         $self->{movement}->{left} + 1;
   } elsif ($name eq 'f5') {
      $self->visibility_radius ($PL_VIS_RAD - 1);
   } elsif ($name eq 'f6') {
      $self->visibility_radius ($PL_VIS_RAD + 1);
   }
   $self->{change} = 1;
}

sub input_mouse_motion : event_cb {
   my ($self, $mx, $my, $xr, $yr) = @_;
   # FIXME: someone ought to fix relativ mouse positions... it's in twos complement here
   #        the SDL module has a bug => motion_yrel returns Uint16 and not Sint16.

   if ($self->{look_lock}) {
      my ($xc, $yc) = ($WIDTH / 2, $HEIGHT / 2);
      my ($xr, $yr) = (($mx - $xc), ($my - $yc));
      my $sens = $self->{res}->{config}->{mouse_sens};
      $self->{yrotate} += ($xr / $WIDTH) * 15 * $sens;
      $self->{xrotate} += ($yr / $HEIGHT) * 15 * $sens;
      $self->{xrotate} = Math::Trig::deg2deg ($self->{xrotate});
      $self->{xrotate} = -90 if $self->{xrotate} < -90;
      $self->{xrotate} = 90 if $self->{xrotate} > 90;
      $self->{yrotate} = Math::Trig::deg2deg ($self->{yrotate});
      delete $self->{cached_look_vec};
      $self->{change} = 1;
      #d# warn "rot ($xr,$yr) ($self->{xrotate},$self->{yrotate})\n";
      SDL::Mouse::warp_mouse ($xc, $yc);
   }
}

sub position_action : event_cb {
}

sub input_mouse_button : event_cb {
   my ($self, $btn, $down) = @_;
   return unless $down;

   my $sbp = $self->{selected_box};
   my $sbbp = $self->{selected_build_box};
   $self->position_action ($sbp, $sbbp, $btn);
}

sub update_player_pos : event_cb {
   my ($self, $pos) = @_;
}

sub visible_chunks_changed : event_cb {
   my ($self, $new, $old, $req) = @_;
   # TODO: $req might be issued again and again with the same chunks,
   #       we should mabye rate limit that for more bandwidth friendly
   #       behaviour
}

sub visibility_radius : event_cb {
   my ($self, $radius) = @_;
   $radius = 6 if $radius > 6; # limit, or it usuall kills server :-/
   $PL_VIS_RAD = $radius;
   $FAR_PLANE = ($radius * 12) * 0.7;
   glFogf (GL_FOG_START, $FAR_PLANE - 20);
   glFogf (GL_FOG_END,   $FAR_PLANE - 1);
   ctr_log (info => "changed visibility radius to %d", $PL_VIS_RAD);
}

=back

=head1 AUTHOR

Robin Redeker, C<< <elmex@ta-sa.org> >>

=head1 COPYRIGHT & LICENSE

Copyright 2011 Robin Redeker, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License.

=cut

1;



( run in 2.623 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )