Clean up. This dir is still on experimental branch
[sdlgit/SDL_perl.git] / test / OpenGL / tutorial / lesson07.pl
CommitLineData
8fde61e3 1#!/usr/bin/perl
2# This code is based on the code by Jeff Molofee '99
3# and ported to SDL by Sam Lantinga '2000
4# Original ported to Perl/SDL by Wayne Keenan '2000
5# And updated by David Goehrig '02
6#
7#
8# Jeff's tutorials can be found at www.demonews.com/hosted/nehe
9
10use strict;
11use Getopt::Long;
12use Data::Dumper;
13use Benchmark;
14
15use SDL;
16use SDL::App;
17use SDL::OpenGL;
18use SDL::Event;
19use SDL::Surface;
20use SDL::OpenGL;
21
22my $arg_screen_width =640;
23my $arg_screen_height=512;
24my $arg_fullscreen=0;
25
26GetOptions(
27 "width:i" => \$arg_screen_width,
28 "height:i" => \$arg_screen_height,
29 "fullscreen!" => \$arg_fullscreen,
30 ) or die $!;
31
32############################################################
33
34my $light = 0;
35
36my $xrot=0; # x rotation
37my $yrot=0; # y rotation
38my $xspeed=0; # x rotation speed
39my $yspeed=0; # y rotation speed
40
41my $z=-5.0; # depth into the screen.
42
43my $filter = 1; # Which Filter To Use (nearest/linear/mipmapped) */
44
45main();
46exit;
47
48sub main
49 {
50 my $done=0;
51 my $vidmode_flags= SDL_OPENGL;
52
53 $vidmode_flags|= SDL_FULLSCREEN if $arg_fullscreen;
54
55 my $app = new SDL::App ( -title => "Jeff Molofee's GL Code Tutorial ... NeHe '99",
56 -icon => "icon.png",
57 -flags => $vidmode_flags,
58 -width => $arg_screen_width,
59 -height =>$arg_screen_height,
60 -opengl => 1,
61 );
62
63 SDL::ShowCursor(0);
64
65 my $event = new SDL::Event;
66 $event->set(SDL_SYSWMEVENT,SDL_IGNORE);
67
68 InitGL($arg_screen_width, $arg_screen_height);
69
70 while ( not $done )
71 {
72
73 DrawGLScene();
74
75 $app->sync();
76
77 $event->pump;
78 $event->poll;
79
80 $done = 1 if ( $event->type == SDL_QUIT ) ;
81
82
83 if ( $event->type == SDL_KEYDOWN )
84 {
85 my $key= $event->key_sym;
86
87 $done = 1 if ( $key == SDLK_ESCAPE ) ;
88
89
90 if ($key==SDLK_l)
91 {
92 printf("Light was: %d\n", $light);
93 $light = $light ? 0 : 1; # switch the current value of light, between 0 and 1.
94 printf("Light is now: %d\n", $light);
95 if (!$light)
96 {
97 glDisable(GL_LIGHTING);
98 }
99 else
100 {
101 glEnable(GL_LIGHTING);
102 }
103
104 }
105 if ($key==SDLK_f)
106 {
107 printf("Filter was: %d\n", $filter);
108 $filter = 1+(($filter) % 3) ;
109 printf("Filter is now: %d\n", $filter);
110 }
111
112 #bit lax:
113 $z-=0.02 if ( $key == SDLK_PAGEUP );
114 $z+=0.02 if ( $key == SDLK_PAGEDOWN );
115 $xspeed+=0.02 if ( $key == SDLK_UP );
116 $xspeed-=0.02 if ( $key == SDLK_DOWN );
117 $yspeed-=0.01 if ( $key == SDLK_LEFT );
118 $yspeed+=0.01 if ( $key == SDLK_RIGHT );
119
120 }
121 }
122 }
123
124
125
126
127
128
129#########################################################################
130#Pretty much in original form, but 'Perlised'
131
132
133
134
135sub InitGL
136 {
137 my ($Width, $Height) = @_;
138
139 glViewport(0, 0, $Width, $Height);
140
141 LoadGLTextures(); # Load The Texture(s)
142
143 glEnable(GL_TEXTURE_2D); # Enable Texture Mapping
144
145
146 glClearColor(0.0, 0.0, 0.0, 0.0); # This Will Clear The Background Color To Black
147 glClearDepth(1.0); # Enables Clearing Of The Depth Buffer
148 glDepthFunc(GL_LESS); # The Type Of Depth Test To Do
149 glEnable(GL_DEPTH_TEST); # Enables Depth Testing
150 glShadeModel(GL_SMOOTH); # Enables Smooth Color Shading
151
152 glMatrixMode(GL_PROJECTION);
153 glLoadIdentity(); # Reset The Projection Matrix
154
155 gluPerspective(45.0, $Width/$Height, 0.1, 100.0); # Calculate The Aspect Ratio Of The Window
156
157 glMatrixMode(GL_MODELVIEW);
158
159
160 my $LightAmbient = [ 0.5, 0.5, 0.5, 1.0 ]; # white ambient light at half intensity (rgba) */
161
162 my $LightDiffuse = [ 1.0, 1.0, 1.0, 1.0 ]; # super bright, full intensity diffuse light. */
163
164 my $LightPosition = [ 0.0 , 0.0, 2.0, 1.0 ]; # position of light (x, y, z, (position of light)) */
165
166
167
168 #hmm, undefine:
169 glLight(GL_LIGHT1, GL_AMBIENT, @$LightAmbient); # add lighting. (ambient)
170 glLight(GL_LIGHT1, GL_DIFFUSE, @$LightDiffuse); # add lighting. (diffuse).
171 glLight(GL_LIGHT1, GL_POSITION,@$LightPosition); # set light position.
172 glEnable(GL_LIGHT1); # turn light 1 on.
173 }
174
175
176
177# The main drawing function.
178sub DrawGLScene
179 {
180 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); # Clear The Screen And The Depth Buffer
181 glLoadIdentity(); # Reset The View
182
183 glTranslate(0.0,0.0,$z); # move z units out from the screen.
184
185 glRotate($xrot,1.0,0.0,0.0); # Rotate On The X Axis
186 glRotate($yrot,0.0,1.0,0.0); # Rotate On The Y Axis
187
188 glBindTexture(GL_TEXTURE_2D, $filter); # choose the texture to use.
189
190 glBegin(GL_QUADS); # begin drawing a cube
191
192 # Front Face (note that the texture's corners have to match the quad's corners)
193 glNormal( 0.0, 0.0, 1.0); # front face points out of the screen on z.
194 glTexCoord(0.0, 0.0); glVertex(-1.0, -1.0, 1.0); # Bottom Left Of The Texture and Quad
195 glTexCoord(1.0, 0.0); glVertex( 1.0, -1.0, 1.0); # Bottom Right Of The Texture and Quad
196 glTexCoord(1.0, 1.0); glVertex( 1.0, 1.0, 1.0); # Top Right Of The Texture and Quad
197 glTexCoord(0.0, 1.0); glVertex(-1.0, 1.0, 1.0); # Top Left Of The Texture and Quad
198
199 # Back Face
200 glNormal( 0.0, 0.0,-1.0); # back face points into the screen on z.
201 glTexCoord(1.0, 0.0); glVertex(-1.0, -1.0, -1.0); # Bottom Right Of The Texture and Quad
202 glTexCoord(1.0, 1.0); glVertex(-1.0, 1.0, -1.0); # Top Right Of The Texture and Quad
203 glTexCoord(0.0, 1.0); glVertex( 1.0, 1.0, -1.0); # Top Left Of The Texture and Quad
204 glTexCoord(0.0, 0.0); glVertex( 1.0, -1.0, -1.0); # Bottom Left Of The Texture and Quad
205
206 # Top Face
207 glNormal( 0.0, 1.0, 0.0); # top face points up on y.
208 glTexCoord(0.0, 1.0); glVertex(-1.0, 1.0, -1.0); # Top Left Of The Texture and Quad
209 glTexCoord(0.0, 0.0); glVertex(-1.0, 1.0, 1.0); # Bottom Left Of The Texture and Quad
210 glTexCoord(1.0, 0.0); glVertex( 1.0, 1.0, 1.0); # Bottom Right Of The Texture and Quad
211 glTexCoord(1.0, 1.0); glVertex( 1.0, 1.0, -1.0); # Top Right Of The Texture and Quad
212
213 # Bottom Face
214 glNormal( 0.0, -1.0, 0.0); # bottom face points down on y.
215 glTexCoord(1.0, 1.0); glVertex(-1.0, -1.0, -1.0); # Top Right Of The Texture and Quad
216 glTexCoord(0.0, 1.0); glVertex( 1.0, -1.0, -1.0); # Top Left Of The Texture and Quad
217 glTexCoord(0.0, 0.0); glVertex( 1.0, -1.0, 1.0); # Bottom Left Of The Texture and Quad
218 glTexCoord(1.0, 0.0); glVertex(-1.0, -1.0, 1.0); # Bottom Right Of The Texture and Quad
219
220 # Right face
221 glNormal( 1.0, 0.0, 0.0); # right face points right on x.
222 glTexCoord(1.0, 0.0); glVertex( 1.0, -1.0, -1.0); # Bottom Right Of The Texture and Quad
223 glTexCoord(1.0, 1.0); glVertex( 1.0, 1.0, -1.0); # Top Right Of The Texture and Quad
224 glTexCoord(0.0, 1.0); glVertex( 1.0, 1.0, 1.0); # Top Left Of The Texture and Quad
225 glTexCoord(0.0, 0.0); glVertex( 1.0, -1.0, 1.0); # Bottom Left Of The Texture and Quad
226
227 # Left Face
228 glNormal(-1.0, 0.0, 0.0); # left face points left on x.
229 glTexCoord(0.0, 0.0); glVertex(-1.0, -1.0, -1.0); # Bottom Left Of The Texture and Quad
230 glTexCoord(1.0, 0.0); glVertex(-1.0, -1.0, 1.0); # Bottom Right Of The Texture and Quad
231 glTexCoord(1.0, 1.0); glVertex(-1.0, 1.0, 1.0); # Top Right Of The Texture and Quad
232 glTexCoord(0.0, 1.0); glVertex(-1.0, 1.0, -1.0); # Top Left Of The Texture and Quad
233
234 glEnd(); # done with the polygon.
235
236 $xrot+=$xspeed; # X Axis Rotation
237 $yrot+=$yspeed; # Y Axis Rotation
238
239
240
241 }
242
243
244
245
246sub LoadGLTextures
247 {
248 # Load Texture
249
250
251 my ($pixels, $width, $height, $size)=ImageLoad("Data/crate.png");
252
253 # Create Texture
254
255 glGenTextures(3);
256
257 # texture 1 (poor quality scaling)
258 glBindTexture(GL_TEXTURE_2D, 1); # 2d texture (x and y size)
259
260 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); # cheap scaling when image bigger than texture
261 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); # cheap scaling when image smalled than texture
262
263 # 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
264 # border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
265 #glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->w, image1->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->pixels);
266
267 glTexImage2D(GL_TEXTURE_2D,
268 0, #level (0 normal, heighr is form mip-mapping)
269 3, #internal format (3=GL_RGB)
270 $width,$height,
271 0, # border
272 GL_RGB, #format RGB color data
273 GL_UNSIGNED_BYTE, #unsigned bye data
274 $pixels); #ptr to texture data
275
276
277
278 # texture 2 (linear scaling)
279 glBindTexture(GL_TEXTURE_2D, 2); # 2d texture (x and y size)
280 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); # scale linearly when image bigger than texture
281 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); # scale linearly when image smalled than texture
282 #glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->w, image1->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->pixels);
283
284 glTexImage2D(GL_TEXTURE_2D,
285 0, #level (0 normal, heighr is form mip-mapping)
286 3, #internal format (3=GL_RGB)
287 $width,$height,
288 0, # border
289 GL_RGB, #format RGB color data
290 GL_UNSIGNED_BYTE, #unsigned bye data
291 $pixels); #ptr to texture data
292
293
294
295
296 # texture 3 (mipmapped scaling)
297 glBindTexture(GL_TEXTURE_2D, 3); # 2d texture (x and y size)
298 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); # scale linearly when image bigger than texture
299 glTexParameter(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); # scale linearly + mipmap when image smalled than texture
300 #glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->w, image1->h, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->pixels);
301
302 glTexImage2D(GL_TEXTURE_2D,
303 0, #level (0 normal, heighr is form mip-mapping)
304 3, #internal format (3=GL_RGB)
305 $width,$height,
306 0, # border
307 GL_RGB, #format RGB color data
308 GL_UNSIGNED_BYTE, #unsigned bye data
309 $pixels); #ptr to texture data
310
311 # 2d texture, 3 colors, width, height, RGB in that order, byte data, and the data.
312 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, $width, $height, GL_RGB, GL_UNSIGNED_BYTE, $pixels);
313
314 my $glerr=glGetError();
315 die "Problem setting up 2d Texture (dimensions not a power of 2?)):".gluErrorString($glerr)."\n" if $glerr;
316
317 }
318
319
320
321
322
323
324
325
326
327
328
329#somthing needs to keep the ref count alive for objects which represents data in C space (they have no ref count):
330my @ref=();
331
332sub ImageLoad
333 {
334 my $filename=shift;
335
336 my $surface = new SDL::Surface( -name => $filename); #makes use of SDL: BMP loader.
337
338
339 my $width=$surface->width();
340 my $height=$surface->height();
341 my $bytespp= $surface->bytes_per_pixel();
342 my $size= $width*$height*$bytespp;
343
344 my $surface_pixels=$surface->pixels();
345 my $surface_size=$width*$height*$surface->bytes_per_pixel();
346 my $raw_pixels = $surface_pixels;
347
348
349
350 #do a conversion (the pixel data is accessable as a simple string)
351
352 my $pixels=$raw_pixels;
353 my $pre_conv= $pixels; #rotate image 180 degrees!
354 my $new_pixels="";
355 for (my $y=0; $y< $height; $y++)
356 {
357 my $y_pos=$y*$width*$bytespp; #calculate offset into the image (a string)
358 my $row=substr ($pre_conv, $y_pos, $width*$bytespp); #extract 1 pixel row
359 $row =~ s/\G(.)(.)(.)/$3$2$1/gms; #turn the BMP BGR order into OpenGL RGB order;
360 $new_pixels.= reverse $row;
361 }
362
363 $raw_pixels = $new_pixels; #put transformed data into C array.
364 push @ref, $raw_pixels, $surface;
365
366 #we could have created another SDL surface frm the '$raw_pixel's... oh well.
367 return ($raw_pixels, $width, $height, $size);
368 }