SDL-Tutorial-3DWorld

 view release on metacpan or  search on metacpan

lib/SDL/Tutorial/3DWorld.pm  view on Meta::CPAN

use SDL::Tutorial::3DWorld::Model                  ();
use SDL::Tutorial::3DWorld::OpenGL                 ();
use SDL::Tutorial::3DWorld::Skybox                 ();
use SDL::Tutorial::3DWorld::Texture                ();
use SDL::Tutorial::3DWorld::Bound;

# Enable GLUT support so we can have teapots and other things
BEGIN {
	OpenGL::glutInit();
}

our $VERSION = '0.33';

# The currently active world
our $CURRENT = undef;

=pod

=head2 new

The C<new> constructor sets up the model for the 3D World, but does not
initiate or start the game itself.

It does not current take any parameters.

=cut

sub new {
	my $class = shift;

	# Are we doing a benchmarking run?
	# If so set the flag and we will abort after 100 seconds.
	my $benchmark = scalar grep { $_ eq '--benchmark' } @_;

	# Create the basic object
	my $self  = bless {
		ARGV           => [ @_ ],
		width          => 1280,
		height         => 1024,
		dt             => 0.1,

		# Debugging or expensive elements we can toggle off.
		# Turning all of these three off gives us a much more
		# accurate assessment on how fast a real world would perform.
		benchmark      => $benchmark,
		hide_debug     => $benchmark ? 1 : 0,
		hide_console   => $benchmark ? 1 : 0,
		hide_expensive => $benchmark ? 1 : 0,
	}, $class;

	# Normally we want fullscreen, but occasionally we might want to
	# disable it because we are on a portrait-orientation monitor
	# or for unobtrusive testing (or it doesn't work on some machine).
	# When showing in a window, drop the size to the window isn't huge.
	$self->{fullscreen} = not grep { $_ eq '--window' } @_;
	unless ( $self->{fullscreen} ) {
		$self->{width}  /= 2;
		$self->{height} /= 2;
	}

	# Text console that overlays the world
	$self->{console} = SDL::Tutorial::3DWorld::Console->new;

	# A pretty skybox background for our world
	$self->{skybox} = SDL::Tutorial::3DWorld::Skybox->new(
		type      => 'jpg',
		directory => $self->sharedir('skybox'),
	);

	# Light the world with a single overhead light
	# that matches the position of the sun.
	$self->{lights} = [
		SDL::Tutorial::3DWorld::Light->new(
			position => [ 360, 405, -400 ],
		),
	];

	# Create the (optional) fog.
	# Because it doesn't really blend with the current skybox,
	# I've tweaked it to try to look like a light ground haze.
	# $self->{fog} = SDL::Tutorial::3DWorld::Fog->new(
		# color => [ 0.5, 0.5, 0.5, 0 ],
		# start => 10.0,
		# end   => 50.0,
	# );

	# Create the landscape
	$self->{landscape} = SDL::Tutorial::3DWorld::Landscape::Infinite->new(
		texture => $self->sharefile('ground.jpg'),
	);

	# Place the camera at a typical eye height a few metres back
	# from the teapots and facing slightly down towards them.
	$self->{camera} = SDL::Tutorial::3DWorld::Camera::God->new(
		# Camera position properties
		X      => 0.0,
		Y      => 1.5,
		Z      => 5.0,
		speed  => $self->dscalar(2),

		# Camera view properties
		height => $self->{height},
		width  => $self->{width},
		fovy   => 45,

		# Actor list and indexes for faster culling
		actors => [ ],
		show   => [ ],
		move   => [ ],
	);

	# The selector is an actor and a special camera tool for
	#(potentially) controlling something in the world.
	$self->{selector} = $self->actor(
		SDL::Tutorial::3DWorld::Actor::GridSelect->new,
	);

	# Add a video screen
	# $self->actor(
		# SDL::Tutorial::3DWorld::Actor::TV->new(
			# position => [ 0, 1, -5 ],



( run in 1.046 second using v1.01-cache-2.11-cpan-39bf76dae61 )