rev |
line source |
nuclear@5
|
1 #include "opengl.h"
|
nuclear@3
|
2 #include "teapot.h"
|
nuclear@3
|
3 #include "teapot_data.h"
|
nuclear@3
|
4
|
nuclear@3
|
5 static void draw_patch(struct vec3 *bez_cp, int *index, int flip, int useg, int vseg, float scale);
|
nuclear@3
|
6
|
nuclear@3
|
7 int patch_subdivision = 6;
|
nuclear@3
|
8
|
nuclear@5
|
9 static int dlist_sub[32];
|
nuclear@5
|
10
|
nuclear@3
|
11 void bezier_teapot(float scale)
|
nuclear@3
|
12 {
|
nuclear@3
|
13 int i;
|
nuclear@3
|
14
|
nuclear@5
|
15 glMatrixMode(GL_MODELVIEW);
|
nuclear@5
|
16
|
nuclear@5
|
17 if(!dlist_sub[patch_subdivision]) {
|
nuclear@5
|
18 dlist_sub[patch_subdivision] = glGenLists(1);
|
nuclear@5
|
19 glNewList(dlist_sub[patch_subdivision], GL_COMPILE);
|
nuclear@5
|
20
|
nuclear@5
|
21 for(i=0; i<NUM_TEAPOT_PATCHES; i++) {
|
nuclear@5
|
22 float flip = teapot_part_flip[i];
|
nuclear@5
|
23 float rot = teapot_part_rot[i];
|
nuclear@5
|
24
|
nuclear@5
|
25 glPushMatrix();
|
nuclear@5
|
26 glTranslatef(0, -3.15 * 0.5, 0);
|
nuclear@5
|
27 glRotatef(rot, 0, 1, 0);
|
nuclear@5
|
28 glScalef(1, 1, flip);
|
nuclear@5
|
29 glRotatef(-90, 1, 0, 0);
|
nuclear@5
|
30
|
nuclear@5
|
31 draw_patch(teapot_verts, teapot_index + i * 16, flip < 0.0 ? 1 : 0, patch_subdivision, patch_subdivision, 1.0);
|
nuclear@5
|
32
|
nuclear@5
|
33 glPopMatrix();
|
nuclear@5
|
34 }
|
nuclear@5
|
35
|
nuclear@5
|
36 glEndList();
|
nuclear@5
|
37 }
|
nuclear@5
|
38
|
nuclear@3
|
39 scale /= 2.0;
|
nuclear@5
|
40 glPushMatrix();
|
nuclear@5
|
41 glScalef(scale, scale, scale);
|
nuclear@5
|
42 glCallList(dlist_sub[patch_subdivision]);
|
nuclear@5
|
43 glPopMatrix();
|
nuclear@3
|
44 }
|
nuclear@3
|
45
|
nuclear@3
|
46 static void draw_patch(struct vec3 *bez_cp, int *index, int flip, int useg, int vseg, float scale)
|
nuclear@3
|
47 {
|
nuclear@3
|
48 static const float uoffs[2][4] = {{0, 0, 1, 1}, {1, 1, 0, 0}};
|
nuclear@3
|
49 static const float voffs[4] = {0, 1, 1, 0};
|
nuclear@3
|
50
|
nuclear@3
|
51 int i, j, k;
|
nuclear@3
|
52 struct vec3 cp[16];
|
nuclear@3
|
53 struct vec3 pt, n;
|
nuclear@3
|
54 float u, v;
|
nuclear@3
|
55 float du = 1.0 / useg;
|
nuclear@3
|
56 float dv = 1.0 / vseg;
|
nuclear@3
|
57
|
nuclear@3
|
58 /* collect control points */
|
nuclear@3
|
59 for(i=0; i<16; i++) {
|
nuclear@3
|
60 cp[i] = bez_cp[index[i]];
|
nuclear@3
|
61 }
|
nuclear@3
|
62
|
nuclear@3
|
63 glBegin(GL_QUADS);
|
nuclear@3
|
64 glColor3f(1, 1, 1);
|
nuclear@3
|
65
|
nuclear@3
|
66 u = 0;
|
nuclear@3
|
67 for(i=0; i<useg; i++) {
|
nuclear@3
|
68 v = 0;
|
nuclear@3
|
69 for(j=0; j<vseg; j++) {
|
nuclear@3
|
70
|
nuclear@3
|
71 for(k=0; k<4; k++) {
|
nuclear@3
|
72 pt = bezier_patch(cp, u + uoffs[flip][k] * du, v + voffs[k] * dv);
|
nuclear@3
|
73
|
nuclear@3
|
74 /* top/bottom normal hack */
|
nuclear@3
|
75 if(pt.z > 3.14) {
|
nuclear@3
|
76 n.x = n.y = 0.0f;
|
nuclear@3
|
77 n.z = 1.0f;
|
nuclear@3
|
78 } else if(pt.z < 0.00001) {
|
nuclear@3
|
79 n.x = n.y = 0.0f;
|
nuclear@3
|
80 n.z = -1.0f;
|
nuclear@3
|
81 } else {
|
nuclear@3
|
82 n = bezier_patch_norm(cp, u + uoffs[flip][k] * du, v + voffs[k] * dv);
|
nuclear@3
|
83 }
|
nuclear@3
|
84
|
nuclear@3
|
85 glTexCoord2f(u, v);
|
nuclear@3
|
86 glNormal3f(n.x, n.y, n.z);
|
nuclear@3
|
87 glVertex3f(pt.x * scale, pt.y * scale, pt.z * scale);
|
nuclear@3
|
88 }
|
nuclear@3
|
89
|
nuclear@3
|
90 v += dv;
|
nuclear@3
|
91 }
|
nuclear@3
|
92 u += du;
|
nuclear@3
|
93 }
|
nuclear@3
|
94
|
nuclear@3
|
95 glEnd();
|
nuclear@3
|
96 }
|