From 78bc758ea19b66116da12c65f02a96754db51c99 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 7 Aug 2020 01:46:44 +0300 Subject: [PATCH] added Utah teapot --- miniglut.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test.c | 7 ++ 2 files changed, 320 insertions(+) diff --git a/miniglut.c b/miniglut.c index b098651..631aac4 100644 --- a/miniglut.c +++ b/miniglut.c @@ -2095,10 +2095,323 @@ void glutWireTorus(float inner_rad, float outer_rad, int sides, int rings) glPopAttrib(); } +#define NUM_TEAPOT_INDICES (sizeof teapot_index / sizeof *teapot_index) +#define NUM_TEAPOT_VERTS (sizeof teapot_verts / sizeof *teapot_verts) + +#define NUM_TEAPOT_PATCHES (NUM_TEAPOT_INDICES / 16) + +#define PATCH_SUBDIV 7 + +static float teapot_part_flip[] = { + 1, 1, 1, 1, /* rim flip */ + 1, 1, 1, 1, /* body1 flip */ + 1, 1, 1, 1, /* body2 flip */ + 1, 1, 1, 1, /* lid patch 1 flip */ + 1, 1, 1, 1, /* lid patch 2 flip */ + 1, -1, /* handle 1 flip */ + 1, -1, /* handle 2 flip */ + 1, -1, /* spout 1 flip */ + 1, -1, /* spout 2 flip */ + 1, 1, 1, 1 /* bottom flip */ +}; + +static float teapot_part_rot[] = { + 0, 90, 180, 270, /* rim rotations */ + 0, 90, 180, 270, /* body patch 1 rotations */ + 0, 90, 180, 270, /* body patch 2 rotations */ + 0, 90, 180, 270, /* lid patch 1 rotations */ + 0, 90, 180, 270, /* lid patch 2 rotations */ + 0, 0, /* handle 1 rotations */ + 0, 0, /* handle 2 rotations */ + 0, 0, /* spout 1 rotations */ + 0, 0, /* spout 2 rotations */ + 0, 90, 180, 270 /* bottom rotations */ +}; + + +static int teapot_index[] = { + /* rim */ + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + /* body1 */ + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + /* body 2 */ + 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + /* lid 1 */ + 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3, + 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3, + 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3, + 96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101, 101, 0, 1, 2, 3, + /* lid 2 */ + 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + /* handle 1 */ + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* handle 2 */ + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 65, 66, 67, + /* spout 1 */ + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + /* spout 2 */ + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + /* bottom */ + 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37, + 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37, + 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37, + 118, 118, 118, 118, 124, 122, 119, 121, 123, 126, 125, 120, 40, 39, 38, 37 +}; + + +static float teapot_verts[][3] = { + { 0.2000, 0.0000, 2.70000 }, { 0.2000, -0.1120, 2.70000 }, + { 0.1120, -0.2000, 2.70000 }, { 0.0000, -0.2000, 2.70000 }, + { 1.3375, 0.0000, 2.53125 }, { 1.3375, -0.7490, 2.53125 }, + { 0.7490, -1.3375, 2.53125 }, { 0.0000, -1.3375, 2.53125 }, + { 1.4375, 0.0000, 2.53125 }, { 1.4375, -0.8050, 2.53125 }, + { 0.8050, -1.4375, 2.53125 }, { 0.0000, -1.4375, 2.53125 }, + { 1.5000, 0.0000, 2.40000 }, { 1.5000, -0.8400, 2.40000 }, + { 0.8400, -1.5000, 2.40000 }, { 0.0000, -1.5000, 2.40000 }, + { 1.7500, 0.0000, 1.87500 }, { 1.7500, -0.9800, 1.87500 }, + { 0.9800, -1.7500, 1.87500 }, { 0.0000, -1.7500, 1.87500 }, + { 2.0000, 0.0000, 1.35000 }, { 2.0000, -1.1200, 1.35000 }, + { 1.1200, -2.0000, 1.35000 }, { 0.0000, -2.0000, 1.35000 }, + { 2.0000, 0.0000, 0.90000 }, { 2.0000, -1.1200, 0.90000 }, + { 1.1200, -2.0000, 0.90000 }, { 0.0000, -2.0000, 0.90000 }, + { -2.0000, 0.0000, 0.90000 }, { 2.0000, 0.0000, 0.45000 }, + { 2.0000, -1.1200, 0.45000 }, { 1.1200, -2.0000, 0.45000 }, + { 0.0000, -2.0000, 0.45000 }, { 1.5000, 0.0000, 0.22500 }, + { 1.5000, -0.8400, 0.22500 }, { 0.8400, -1.5000, 0.22500 }, + { 0.0000, -1.5000, 0.22500 }, { 1.5000, 0.0000, 0.15000 }, + { 1.5000, -0.8400, 0.15000 }, { 0.8400, -1.5000, 0.15000 }, + { 0.0000, -1.5000, 0.15000 }, { -1.6000, 0.0000, 2.02500 }, + { -1.6000, -0.3000, 2.02500 }, { -1.5000, -0.3000, 2.25000 }, + { -1.5000, 0.0000, 2.25000 }, { -2.3000, 0.0000, 2.02500 }, + { -2.3000, -0.3000, 2.02500 }, { -2.5000, -0.3000, 2.25000 }, + { -2.5000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 2.02500 }, + { -2.7000, -0.3000, 2.02500 }, { -3.0000, -0.3000, 2.25000 }, + { -3.0000, 0.0000, 2.25000 }, { -2.7000, 0.0000, 1.80000 }, + { -2.7000, -0.3000, 1.80000 }, { -3.0000, -0.3000, 1.80000 }, + { -3.0000, 0.0000, 1.80000 }, { -2.7000, 0.0000, 1.57500 }, + { -2.7000, -0.3000, 1.57500 }, { -3.0000, -0.3000, 1.35000 }, + { -3.0000, 0.0000, 1.35000 }, { -2.5000, 0.0000, 1.12500 }, + { -2.5000, -0.3000, 1.12500 }, { -2.6500, -0.3000, 0.93750 }, + { -2.6500, 0.0000, 0.93750 }, { -2.0000, -0.3000, 0.90000 }, + { -1.9000, -0.3000, 0.60000 }, { -1.9000, 0.0000, 0.60000 }, + { 1.7000, 0.0000, 1.42500 }, { 1.7000, -0.6600, 1.42500 }, + { 1.7000, -0.6600, 0.60000 }, { 1.7000, 0.0000, 0.60000 }, + { 2.6000, 0.0000, 1.42500 }, { 2.6000, -0.6600, 1.42500 }, + { 3.1000, -0.6600, 0.82500 }, { 3.1000, 0.0000, 0.82500 }, + { 2.3000, 0.0000, 2.10000 }, { 2.3000, -0.2500, 2.10000 }, + { 2.4000, -0.2500, 2.02500 }, { 2.4000, 0.0000, 2.02500 }, + { 2.7000, 0.0000, 2.40000 }, { 2.7000, -0.2500, 2.40000 }, + { 3.3000, -0.2500, 2.40000 }, { 3.3000, 0.0000, 2.40000 }, + { 2.8000, 0.0000, 2.47500 }, { 2.8000, -0.2500, 2.47500 }, + { 3.5250, -0.2500, 2.49375 }, { 3.5250, 0.0000, 2.49375 }, + { 2.9000, 0.0000, 2.47500 }, { 2.9000, -0.1500, 2.47500 }, + { 3.4500, -0.1500, 2.51250 }, { 3.4500, 0.0000, 2.51250 }, + { 2.8000, 0.0000, 2.40000 }, { 2.8000, -0.1500, 2.40000 }, + { 3.2000, -0.1500, 2.40000 }, { 3.2000, 0.0000, 2.40000 }, + { 0.0000, 0.0000, 3.15000 }, { 0.8000, 0.0000, 3.15000 }, + { 0.8000, -0.4500, 3.15000 }, { 0.4500, -0.8000, 3.15000 }, + { 0.0000, -0.8000, 3.15000 }, { 0.0000, 0.0000, 2.85000 }, + { 1.4000, 0.0000, 2.40000 }, { 1.4000, -0.7840, 2.40000 }, + { 0.7840, -1.4000, 2.40000 }, { 0.0000, -1.4000, 2.40000 }, + { 0.4000, 0.0000, 2.55000 }, { 0.4000, -0.2240, 2.55000 }, + { 0.2240, -0.4000, 2.55000 }, { 0.0000, -0.4000, 2.55000 }, + { 1.3000, 0.0000, 2.55000 }, { 1.3000, -0.7280, 2.55000 }, + { 0.7280, -1.3000, 2.55000 }, { 0.0000, -1.3000, 2.55000 }, + { 1.3000, 0.0000, 2.40000 }, { 1.3000, -0.7280, 2.40000 }, + { 0.7280, -1.3000, 2.40000 }, { 0.0000, -1.3000, 2.40000 }, + { 0.0000, 0.0000, 0.00000 }, { 1.4250, -0.7980, 0.00000 }, + { 1.5000, 0.0000, 0.07500 }, { 1.4250, 0.0000, 0.00000 }, + { 0.7980, -1.4250, 0.00000 }, { 0.0000, -1.5000, 0.07500 }, + { 0.0000, -1.4250, 0.00000 }, { 1.5000, -0.8400, 0.07500 }, + { 0.8400, -1.5000, 0.07500 } +}; + +static void draw_patch(int *index, int flip, float scale); +static float bernstein(int i, float x); + void glutSolidTeapot(float size) { + int i; + + size /= 2.0; + + for(i=0; i> 1); + x = *(float*)&i; + x = x * (1.5f - xhalf * x * x); + return x; +} + + +#define CROSS(res, a, b) \ + do { \ + (res)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \ + (res)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \ + (res)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \ + } while(0) + +#define NORMALIZE(v) \ + do { \ + float s = rsqrt((v)[0] * (v)[0] + (v)[1] * (v)[1] + (v)[2] * (v)[2]); \ + (v)[0] *= s; \ + (v)[1] *= s; \ + (v)[2] *= s; \ + } while(0) + +#define DT 0.001 + +static void bezier_patch_norm(float *res, float *cp, float u, float v) +{ + float tang[3], bitan[3], tmp[3]; + + bezier_patch(tang, cp, u + DT, v); + bezier_patch(tmp, cp, u - DT, v); + tang[0] -= tmp[0]; + tang[1] -= tmp[1]; + tang[2] -= tmp[2]; + + bezier_patch(bitan, cp, u, v + DT); + bezier_patch(tmp, cp, u, v - DT); + bitan[0] -= tmp[0]; + bitan[1] -= tmp[1]; + bitan[2] -= tmp[2]; + + CROSS(res, tang, bitan); + NORMALIZE(res); +} + + + +static float bernstein(int i, float x) +{ + float invx = 1.0f - x; + + switch(i) { + case 0: + return invx * invx * invx; + case 1: + return 3.0f * x * invx * invx; + case 2: + return 3.0f * x * x * invx; + case 3: + return x * x * x; + default: + break; + } + return 0.0f; +} + +static void draw_patch(int *index, int flip, float scale) +{ + static const float uoffs[2][4] = {{0, 0, 1, 1}, {1, 1, 0, 0}}; + static const float voffs[4] = {0, 1, 1, 0}; + + int i, j, k; + float cp[16 * 3]; + float pt[3], n[3]; + float u, v; + float du = 1.0 / PATCH_SUBDIV; + float dv = 1.0 / PATCH_SUBDIV; + + /* collect control points */ + for(i=0; i<16; i++) { + cp[i * 3] = teapot_verts[index[i]][0]; + cp[i * 3 + 1] = teapot_verts[index[i]][1]; + cp[i * 3 + 2] = teapot_verts[index[i]][2]; + } + + glBegin(GL_QUADS); + glColor3f(1, 1, 1); + + u = 0; + for(i=0; i 3.14) { + n[0] = n[1] = 0.0f; + n[2] = 1.0f; + } else if(pt[2] < 0.00001) { + n[0] = n[1] = 0.0f; + n[2] = -1.0f; + } else { + bezier_patch_norm(n, cp, u + uoffs[flip][k] * du, v + voffs[k] * dv); + } + + glTexCoord2f(u, v); + glNormal3fv(n); + glVertex3f(pt[0] * scale, pt[1] * scale, pt[2] * scale); + } + + v += dv; + } + u += du; + } + + glEnd(); +} diff --git a/test.c b/test.c index 762fea6..bac41ea 100644 --- a/test.c +++ b/test.c @@ -124,6 +124,13 @@ void display(void) glutSolidCone(1.1, 2, 16, 2); glPopMatrix(); + glPushMatrix(); + glTranslatef(0, -0.5, 2.5); + glFrontFace(GL_CW); + glutSolidTeapot(1.0); + glFrontFace(GL_CCW); + glPopMatrix(); + glBegin(GL_QUADS); glNormal3f(0, 1, 0); glVertex3f(-5, -1.3, 5); -- 1.7.10.4