PageRenderTime 65ms CodeModel.GetById 14ms app.highlight 47ms RepoModel.GetById 1ms app.codeStats 0ms

/t_backcompat/OpenGL/tutorial/lesson18.pl

http://github.com/PerlGameDev/SDL
Perl | 411 lines | 321 code | 69 blank | 21 comment | 11 complexity | c181e6792f8bd1411d264a956cc8ce22 MD5 | raw file
  1#!/usr/bin/perl 
  2# This code was created by Jeff Molofee '99
  3# (ported to SDL by Sam Lantinga '2000)
  4# (ported to Linux/SDL by Ti Leggett '01)
  5
  6# Lesson18 adapted by JusTiCe8 @2007 from others lesson and
  7# 	ported to new Perl SDL, comments stripped (see Nehe lessons)
  8
  9# If you've found this code useful, please let me know.
 10
 11# Visit Jeff at http://nehe.gamedev.net/
 12
 13# or for port-specific comments, questions, bugreports etc.
 14# email to leggett@eecs.tulane.edu (C/SDL)
 15# or justice8@wanadoo.fr (SDL-Perl)
 16
 17use strict;
 18use Getopt::Long;
 19
 20use SDL::Constants;
 21use SDLx::App;
 22use SDL::OpenGL::Constants;
 23use SDL::OpenGL;
 24use SDL::Event;
 25use SDL::Cursor;
 26
 27use constant NUM_TEXTURES => 3;
 28
 29my $arg_screen_width  = 640;
 30my $arg_screen_height = 480;
 31my $arg_fullscreen    = 0;
 32my $delay             = 5;
 33
 34my $light = 0;
 35
 36my ( $part1, $part2 );
 37my ( $p1, $p2 ) = ( 0, 1 );
 38
 39my ( $xrot, $yrot, $xspeed, $yspeed );
 40my $z = -5.0;
 41
 42my $LightAmbient  = [ 0.5, 0.5, 0.5, 1.0 ];
 43my $LightDiffuse  = [ 1.0, 1.0, 1.0, 1.0 ];
 44my $LightPosition = [ 0.0, 0.0, 2.0, 1.0 ];
 45
 46my $quadratic;
 47my $object = 5;
 48my $filter = 1;
 49
 50# this flag is used to limit key strokes event
 51my $pressed = 0;
 52
 53GetOptions(
 54	"width:i"     => \$arg_screen_width,
 55	"height:i"    => \$arg_screen_height,
 56	"fullscreen!" => \$arg_fullscreen,
 57	"delay:i"     => \$delay,
 58) or die $!;
 59
 60main();
 61exit;
 62
 63sub main {
 64	my $done         = 0;
 65	my $fps          = 0.0;
 66	my $frames_drawn = 0;
 67
 68	my $app = SDLx::App->new(
 69		-title  => "Jeff Molofee's lesson18: Quadratic",
 70		-icon   => "icon.png",
 71		-width  => $arg_screen_width,
 72		-height => $arg_screen_height,
 73		-opengl => 1,
 74	);
 75
 76	$app->fullscreen if ($arg_fullscreen);
 77
 78	SDL::ShowCursor(0);
 79
 80	my $event = SDL::Event->new;
 81	$event->set( SDL_SYSWMEVENT(), SDL_IGNORE() );
 82
 83	InitGL( $arg_screen_width, $arg_screen_height );
 84
 85	my $prev_ticks  = $app->ticks();
 86	my $fps_counter = 0.0;
 87
 88	while ( !$done ) {
 89		DrawGLScene();
 90
 91		$app->sync();
 92		$app->delay($delay) if ( $delay > 0 );
 93		$frames_drawn++;
 94
 95		my $ticks_now = $app->ticks();
 96		$fps_counter += $ticks_now - $prev_ticks;
 97		$prev_ticks = $ticks_now;
 98
 99		if ( $fps_counter >= 5000.0 ) {
100			$fps = $frames_drawn / ( $fps_counter / 1000.0 );
101			printf(
102				"%d frames in %.2f seconds = %.3f FPS\n",
103				$frames_drawn, $fps_counter / 1000.0, $fps
104			);
105			$frames_drawn = 0;
106			$fps_counter  = 0.0;
107		}
108
109		$event->pump;
110		$event->poll;
111
112		$done = 1 if ( $event->type == &SDL_QUIT );
113
114		if ( $event->type == &SDL_KEYDOWN ) {
115			$done = 1 if ( $event->key_sym == &SDLK_ESCAPE );
116
117			if ( $event->key_sym == &SDLK_f and !$pressed ) {
118				$filter = 1 + $filter % 3;
119
120				#print "Filter = $filter\n";
121				$pressed = 1;
122			} elsif ( $event->key_sym == &SDLK_l and !$pressed ) {
123				$light = !$light;
124				if ( !$light ) {
125					glDisable(&GL_LIGHTING);
126				} else {
127					glEnable(&GL_LIGHTING);
128				}
129				$pressed = 1;
130			} elsif ( $event->key_sym == &SDLK_SPACE and !$pressed ) {
131				$object  = ++$object % 6;
132				$pressed = 1;
133			} elsif ( $event->key_sym == &SDLK_PAGEUP ) {
134				$z -= 0.02;
135			} elsif ( $event->key_sym == &SDLK_PAGEDOWN ) {
136				$z += 0.02;
137			} elsif ( $event->key_sym == &SDLK_UP ) {
138				$xspeed -= 0.01;
139			} elsif ( $event->key_sym == &SDLK_DOWN ) {
140				$xspeed += 0.01;
141			} elsif ( $event->key_sym == &SDLK_RIGHT ) {
142				$yspeed += 0.01;
143			} elsif ( $event->key_sym == &SDLK_LEFT ) {
144				$yspeed -= 0.01;
145			}
146		} elsif ( $event->type == &SDL_KEYUP ) {
147			$pressed = 0;
148		}
149	}
150}
151
152sub InitGL {
153	my ( $Width, $Height ) = @_;
154	( $xrot, $yrot ) = ( 0.0, 0.0 );
155
156	glViewport( 0, 0, $Width, $Height );
157
158	LoadGLTexture();
159	glEnable(&GL_TEXTURE_2D);
160	glShadeModel(&GL_SMOOTH);
161
162	glClearColor( 0.0, 0.0, 0.0, 0.0 );
163	glClearDepth(1.0);
164
165	glEnable(&GL_DEPTH_TEST);
166	glDepthFunc(&GL_LESS); # GL_EQUAL as source tutorial don't work (?)
167	glHint( &GL_PERSPECTIVE_CORRECTION_HINT, &GL_NICEST );
168
169	glLight( &GL_LIGHT1, &GL_AMBIENT,  @$LightAmbient );
170	glLight( &GL_LIGHT1, &GL_DIFFUSE,  @{$LightDiffuse} );
171	glLight( &GL_LIGHT1, &GL_POSITION, @{$LightPosition} );
172
173	glEnable(&GL_LIGHT1);
174
175	$quadratic = gluNewQuadric();
176
177	#gluQuadricNormals ( $quadratic, &GLU_SMOOTH );
178	gluQuadricTexture( $quadratic, &GL_TRUE );
179
180	glMatrixMode(&GL_PROJECTION);
181	glLoadIdentity();
182
183	gluPerspective( 45.0, $Width / $Height, 0.1, 100.0 );
184
185	glMatrixMode(&GL_MODELVIEW);
186}
187
188sub drawGLCube {
189	glBegin(&GL_QUADS);
190
191	glNormal( 0.0, 0.0, 1.0 );
192	glTexCoord( 1.0, 0.0 );
193	glVertex( -1.0, -1.0, 1.0 );
194	glTexCoord( 0.0, 0.0 );
195	glVertex( 1.0, -1.0, 1.0 );
196	glTexCoord( 0.0, 1.0 );
197	glVertex( 1.0, 1.0, 1.0 );
198	glTexCoord( 1.0, 1.0 );
199	glVertex( -1.0, 1.0, 1.0 );
200
201	glNormal( 0.0, 0.0, -1.0 );
202	glTexCoord( 0.0, 0.0 );
203	glVertex( -1.0, -1.0, -1.0 );
204	glTexCoord( 0.0, 1.0 );
205	glVertex( -1.0, 1.0, -1.0 );
206	glTexCoord( 1.0, 1.0 );
207	glVertex( 1.0, 1.0, -1.0 );
208	glTexCoord( 1.0, 0.0 );
209	glVertex( 1.0, -1.0, -1.0 );
210
211	glNormal( 0.0, 1.0, 0.0 );
212	glTexCoord( 1.0, 1.0 );
213	glVertex( -1.0, 1.0, -1.0 );
214	glTexCoord( 1.0, 0.0 );
215	glVertex( -1.0, 1.0, 1.0 );
216	glTexCoord( 0.0, 0.0 );
217	glVertex( 1.0, 1.0, 1.0 );
218	glTexCoord( 0.0, 1.0 );
219	glVertex( 1.0, 1.0, -1.0 );
220
221	glNormal( 0.0, -1.0, 0.0 );
222	glTexCoord( 0.0, 1.0 );
223	glVertex( -1.0, -1.0, -1.0 );
224	glTexCoord( 1.0, 1.0 );
225	glVertex( 1.0, -1.0, -1.0 );
226	glTexCoord( 1.0, 0.0 );
227	glVertex( 1.0, -1.0, 1.0 );
228	glTexCoord( 0.0, 0.0 );
229	glVertex( -1.0, -1.0, 1.0 );
230
231	glNormal( 1.0, 0.0, 0.0 );
232	glTexCoord( 0.0, 0.0 );
233	glVertex( 1.0, -1.0, -1.0 );
234	glTexCoord( 0.0, 1.0 );
235	glVertex( 1.0, 1.0, -1.0 );
236	glTexCoord( 1.0, 1.0 );
237	glVertex( 1.0, 1.0, 1.0 );
238	glTexCoord( 1.0, 0.0 );
239	glVertex( 1.0, -1.0, 1.0 );
240
241	glNormal( -1.0, 0.0, 0.0 );
242	glTexCoord( 1.0, 0.0 );
243	glVertex( -1.0, -1.0, -1.0 );
244	glTexCoord( 0.0, 0.0 );
245	glVertex( -1.0, -1.0, 1.0 );
246	glTexCoord( 0.0, 1.0 );
247	glVertex( -1.0, 1.0, 1.0 );
248	glTexCoord( 1.0, 1.0 );
249	glVertex( -1.0, 1.0, -1.0 );
250
251	glEnd();
252}
253
254sub DrawGLScene {
255	glClear( &GL_COLOR_BUFFER_BIT | &GL_DEPTH_BUFFER_BIT );
256	glLoadIdentity();
257
258	glTranslate( 0.0, 0.0, $z );
259
260	glRotate( $xrot, 1.0, 0.0, 0.0 );
261	glRotate( $yrot, 0.0, 1.0, 0.0 );
262
263	glBindTexture( &GL_TEXTURE_2D, $filter );
264
265	if ( $object == 0 ) {
266		drawGLCube();
267	} elsif ( $object == 1 ) {
268		glTranslate( 0.0, 0.0, -1.5 );
269		gluCylinder( $quadratic, 1.0, 1.0, 3.0, 32, 32 );
270	} elsif ( $object == 2 ) {
271		gluDisk( $quadratic, 0.5, 1.5, 32, 32 );
272	} elsif ( $object == 3 ) {
273		gluSphere( $quadratic, 1.3, 32, 32 );
274	} elsif ( $object == 4 ) {
275		glTranslate( 0.0, 0.0, -1.5 );
276		gluCylinder( $quadratic, 1.0, 0.0, 3.0, 32, 32 );
277	} elsif ( $object == 5 ) {
278		$part1 += $p1;
279		$part2 += $p2;
280		if ( $part1 > 359 ) {
281			$p1    = 0;
282			$part1 = 0;
283			$p2    = 1;
284			$part2 = 0;
285		}
286		if ( $part2 > 359 ) {
287			$p1 = 1;
288			$p2 = 0;
289		}
290
291		gluPartialDisk( $quadratic, 0.5, 1.5, 32, 32, $part1, $part2 - $part1 );
292	}
293
294	$xrot += $xspeed;
295	$yrot += $yspeed;
296}
297
298sub LoadGLTexture {
299	my ( $pixels, $width, $height, $size ) = ImageLoad('data/wall.bmp');
300
301	#print "LoadGLTexture: w:$width h:$height s:$size\n";
302
303	my $textures = glGenTextures(NUM_TEXTURES);
304	unless ( $$textures[0] ) {
305		print "Could not generate textures\n";
306		return 0;
307	}
308
309	glBindTexture( &GL_TEXTURE_2D, 1 ); #$$textures[0]);
310
311	glTexImage2D(
312		&GL_TEXTURE_2D,    0, 3, $width, $height, 0, &GL_BGR,
313		&GL_UNSIGNED_BYTE, $pixels
314	);
315
316	glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_NEAREST );
317	glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER, &GL_NEAREST );
318
319	glBindTexture( &GL_TEXTURE_2D, 2 );
320
321	glTexImage2D(
322		&GL_TEXTURE_2D,    0, 3, $width, $height, 0, &GL_BGR,
323		&GL_UNSIGNED_BYTE, $pixels
324	);
325
326	glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER, &GL_LINEAR );
327	glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_LINEAR );
328
329	glBindTexture( &GL_TEXTURE_2D, 3 );
330
331	glTexParameter(
332		&GL_TEXTURE_2D, &GL_TEXTURE_MIN_FILTER,
333		&GL_LINEAR_MIPMAP_NEAREST
334	);
335	glTexParameter( &GL_TEXTURE_2D, &GL_TEXTURE_MAG_FILTER, &GL_LINEAR );
336
337	gluBuild2DMipmaps(
338		&GL_TEXTURE_2D,    3, $width, $height, &GL_BGR,
339		&GL_UNSIGNED_BYTE, $pixels
340	);
341
342	my $glerr = glGetError();
343	if ($glerr) {
344		print "Problem setting up 2d Texture (dimensions not a power of 2?)): " . gluErrorString($glerr) . "\n";
345		return 0;
346	}
347}
348
349sub ImageLoad {
350	my $filename = shift;
351	return unless ( defined $filename and -e $filename );
352
353	#somthing needs to keep the ref count alive for objects which represents data in C space (they have no ref count):
354	my @ref = ();
355
356	#makes use of SDL: BMP loader.
357	my $surface = SDL::Surface->new( -name => $filename );
358
359	my $width   = $surface->width();
360	my $height  = $surface->height();
361	my $bytespp = $surface->bytes_per_pixel();
362	my $size    = $width * $height * $bytespp;
363
364	return ( $surface->pixels(), $width, $height, $size );
365
366	my $surface_pixels = $surface->pixels();
367	my $surface_size   = $width * $height * $surface->bytes_per_pixel();
368	my $raw_pixels     = reverse $surface_pixels;
369
370	#do a conversion (the pixel data is accessable as a simple string)
371	my $pixels     = $raw_pixels;
372	my $pre_conv   = $pixels;
373	my $new_pixels = '';
374
375	for ( my $y = 0; $y < $height; $y++ ) {
376
377		# calculate offset into the image (a string)
378		my $y_pos = $y * $width * $bytespp;
379
380		# extract 1 pixel row
381		my $row = substr( $pre_conv, $y_pos, $width * $bytespp );
382
383		# turn the BMP BGR order into OpenGL RGB order;
384		$row =~ s/\G(.)(.)(.)/$3$2$1/gms;
385		$new_pixels .= reverse $row;
386	}
387
388	$raw_pixels = $new_pixels;
389	push @ref, $raw_pixels, $surface;
390
391	# we could have created another SDL surface frm the '$raw_pixel's... oh well.
392	return ( $raw_pixels, $width, $height, $size );
393}
394
395END {
396	gluDeleteQuadric($quadratic);
397	$quadratic = undef;
398
399=item rem
400	use Devel::Peek;
401	print "Q=$quadratic\n";
402	mstat;
403	Dump ($quadratic, 5);
404	gluDeleteQuadric ($quadratic);
405	Dump ($quadratic, 5);
406	$quadratic = undef;
407	print "Q=$quadratic\n";
408	Dump ($quadratic, 5);
409=cut
410
411}