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 )