First commit of SDL_Perl-2.1.3
[sdlgit/SDL_perl.git] / test / OpenGL / test5.pl
1 #!/usr/bin/env perl
2 #
3 # Bezier Surface example 
4 #
5
6 use SDL;
7 use SDL::App;
8 use SDL::Event;
9 use SDL::OpenGL;
10
11 my $app = new SDL::App  -w => 800, -h => 600, -d => 16, -gl => 1;
12
13 my $knots = pack "f8", 0,0,0,0,1,1,1,1;
14 my $edgePts = pack "f10", 0,0,1,0,1,1,0,1,0,0;
15 my $curvePts = pack "f8", 0.25,0.5,0.25,0.75,0.75,0.75,0.75,0.5;
16 my $curveKnots = pack "f8", 0,0,0,0,1,1,1,1;
17 my $pwlPts = pack "f8", 0.75, 0.5, 0.5, 0.25, 0.25, 0.5, 0, 0;
18
19 sub init {
20         glViewport(0,0,800,600);
21         glMatrixMode(GL_PROJECTION());
22         glLoadIdentity();
23         glFrustum (-0.1,0.1,-0.075,0.075,0.3,100.0 );
24         glMatrixMode(GL_MODELVIEW());
25         glLoadIdentity();
26         glTranslate(0,0,-15);
27         glClearColor(0.0, 0.0, 0.0, 0.0);       
28         glShadeModel(GL_SMOOTH());
29 }
30
31 sub initlight {
32         glEnable(GL_LIGHTING());
33         glEnable(GL_LIGHT0());
34         glEnable(GL_DEPTH_TEST());
35         glEnable(GL_AUTO_NORMAL());
36         glEnable(GL_NORMALIZE());
37         glLight(GL_LIGHT0(),GL_AMBIENT(),0.3,0.3,0.3,1.0);
38         glLight(GL_LIGHT0(),GL_POSITION(), 1.0,0.0,2.0,1.0);
39         glMaterial(GL_FRONT(), GL_DIFFUSE(),0.6,0.6,0.6,1.0);
40         glMaterial(GL_FRONT(), GL_SPECULAR(), 1.0, 1.0, 1.0, 1.0);
41         glMaterial(GL_FRONT(), GL_SHININESS(), 40.0);
42 }
43
44 my ($a,$b) = (0,90);
45
46 my $ctrldata;
47 sub initpts {
48         my @points;
49         for my $u ( 0 .. 3 ) {
50                 for my $v ( 0 .. 3 ) {
51                         push @points, 2.0 * ($u - 1.5);
52                         push @points, 2.0 * ($v - 1.5);
53                         if (( $u == 1 || $u == 2 ) && ( $v == 1 || $v == 2 )) {
54                                 push @points,  3.0;
55                         } else {
56                                 push @points, -3.0;
57                         }
58                 }
59         }
60         $ctrldata = pack "f48", @points;
61 }
62
63 sub display {
64         glClear(GL_COLOR_BUFFER_BIT() | GL_DEPTH_BUFFER_BIT());
65         glPushMatrix();
66         glRotate($a%360,0,1,0);
67         glRotate($b%360,-1,0,0);
68         glScale(0.5,0.5,0.5);
69         $nurb = gluNewNurbsRenderer();
70         gluNurbsProperty($nurb,GLU_CULLING,GL_TRUE);
71         gluBeginSurface($nurb);
72                 gluNurbsSurface($nurb, 8, $knots, 8, $knots, 
73                         4*3, 3, $ctrldata, 
74                         4, 4, GL_MAP2_VERTEX_3);
75         if ($toggle) {
76                 gluBeginTrim($nurb);
77                         gluPwlCurve($nurb,5,$edgePts,2,GLU_MAP1_TRIM_2);
78                 gluEndTrim($nurb);
79                 gluBeginTrim($nurb);
80                         gluNurbsCurve($nurb,8,$curveKnots, 2, $curvePts, 4, GLU_MAP1_TRIM_2);
81                         gluPwlCurve($nurb,3,$pwlPts,2,GLU_MAP1_TRIM_2);
82                 gluEndTrim($nurb);
83         }
84                 
85         gluEndSurface($nurb);
86
87         glPopMatrix();
88         $app->sync();
89 }
90
91 init();
92 initlight();
93 initpts();
94 display();
95
96 print STDERR <<USAGE;
97 Press:
98 q                       Quit
99 t                       Toggle Curve & Trim
100 f                       Toggle Fullscreen
101 Up/Down/Left/Right      Rotate
102
103 USAGE
104
105 my $event = new SDL::Event;
106 $app->loop ({
107                 SDL_QUIT() => sub { exit(); }, 
108                 SDL_KEYDOWN() => sub { 
109                         my ($event) = @_;
110                         if ( $event->key_sym() == SDLK_f ) {
111                                 $app->fullscreen();
112                                 display(); 
113                         } elsif ( $event->key_sym() == SDLK_t ) {
114                                 $toggle = $toggle ? 0 : 1;
115                                 display();
116                         } elsif ( $event->key_sym() == SDLK_q ) {
117                                 exit();
118                         } else {
119                                 if ($event->key_sym() == SDLK_LEFT()) {
120                                         $a -= 10; 
121                                 } elsif ($event->key_sym() == SDLK_RIGHT()) {
122                                         $a += 10; 
123                                 } elsif ($event->key_sym() == SDLK_UP()) {
124                                         $b += 10;
125                                 } elsif ($event->key_sym() == SDLK_DOWN()) {
126                                         $b -= 10;       
127                                 }
128                                 display(); 
129                         }
130                 },
131 });
132