Commit | Line | Data |
8fde61e3 |
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 | |