Anonymous user
Catmull–Clark subdivision surface/C: Difference between revisions
tweaks for better display
(performance fix) |
(tweaks for better display) |
||
Line 6:
#include <stdarg.h>
#include <math.h>
#include <GL/gl.h>
Line 28 ⟶ 27:
int max_depth = 7;
int flat_shade = 0;▼
int show_parent = 1;
int wireframe_mode =
int face_mode = 1;
int model_idx = 0;
#define new_struct(type, var) type var = calloc(sizeof(type##_t), 1)
Line 131:
typedef struct vertex_t {
coord_t pos, avg_norm;
list e, f;
struct vertex_t * v_new;
Line 260:
#define tri_face(m, a, b, c) model_add_face(m, 3, a, b, c)
#define face_v(f, i) ((vertex)(f->v->buf[i]))
int model_add_face_v(model m, list vl
{
int i
vertex
edge e;
face f = face_new();
Line 270:
for (i = 1; i <= n; i++, v0 = v1) {
v1 = elem(vl, i % len(vl));
foreach(j, v, m->v)▼
if (j == len(m->v))▼
}▼
list_push(v1->f, f);
Line 286 ⟶ 278:
list_push(f->v, v1);
}
coord_t d1, d2;▼
vsub(&(face_v(f, 1)->pos), &(face_v(f, 0)->pos), &d1),▼
vsub(&(face_v(f, 2)->pos), &(face_v(f, 1)->pos), &d2),▼
&(f->norm)));▼
return list_push(m->f, f);
Line 310 ⟶ 296:
va_end(ap);
x = model_add_face_v(m, lst
list_del(lst);
return x;
}
void model_norms(model m)
{
int i, j, n;▼
face f;▼
vertex v, v0, v1;▼
▲ coord_t d1, d2, norm;
foreach(i, v, f->v) {
v0 = elem(f->v, i ? i - 1 : n - 1);
v1 = elem(f->v, (i + 1) % n);
vcross(&d1, &d2, &norm);
▲ }
if (i > 1) vnormalize(&f->norm);
}
foreach(i, v, m->v) {
foreach(j, f, v->f)
vadd(v->avg_norm, f->norm);
if (j > 1) vnormalize(&(v->avg_norm));
}
printf("New model: %d faces\n", len(m->f));
}
Line 409 ⟶ 423:
}
}
model_norms(nm);
return nm;
}
Line 442 ⟶ 458:
tri_face(m, 2, 11, 12);
tri_face(m, 3, 12, 13);
tri_face(m, 0, 10, 5);
Line 455 ⟶ 471:
tri_face(m, 0, 9, 14);
//model_add_face(m, 5, 14, 13, 12, 11, 10);
//model_add_face(m, 5, 5, 6, 7, 8, 9);
model_norms(m);
return m;
}
Line 493 ⟶ 510:
quad_face(m, 15, 14, 6, 7);
model_norms(m);
return m;
}
Line 512 ⟶ 530:
quad_face(m, 0, 2, 6, 4);
quad_face(m, 5, 7, 3, 1);
model_norms(m);
return m;
}
void draw_model(model m)
{
int i, j;
face f;
vertex v;
foreach(i, f, m->f) {
glBegin(GL_POLYGON);▼
if (!interp_norm) glNormal3fv(&(f->norm.x));▼
if (interp_norm)
glNormal3fv(&(v->avg_norm.x));
}
glEnd();▼
}
}
Line 521 ⟶ 558:
glDisable(GL_LIGHTING);
foreach(i, e, m->e) {
if (e->f->n != 2) glColor3fv(hole_color);
else glColor3fv(color);
glBegin(
glVertex3fv(&(e->v[0]->pos.x));
glVertex3fv(&(e->v[1]->pos.x));
Line 535 ⟶ 571:
void draw_faces(model m)
{
▲ int i, j;
▲ face f;
▲ vertex v;
glPushMatrix();
glLoadIdentity();
Line 552 ⟶ 584:
glPopMatrix();
if (wireframe_mode) {
▲ foreach(i, f, m->f) {
glEnable(GL_POLYGON_OFFSET_FILL);
▲ glBegin(GL_POLYGON);
glPolygonOffset(1.0, 1.0);
▲ glNormal3fv(&(f->norm.x));
▲ foreach(j, v, f->v) glVertex3fv(&(v->pos.x));
▲ glEnd();
}
draw_model(m);
if (wireframe_mode)
glDisable(GL_POLYGON_OFFSET_FILL);
}
Line 606 ⟶ 637:
return;
case 'w':
wireframe_mode =
return;
case 'l':
Line 628 ⟶ 659:
return;
case 's':
interp_norm = !interp_norm;
break;
case 'p':
show_parent = (show_parent + 1) % 3;
Line 679 ⟶ 708:
model m = elem(models, model_pos);
if (wireframe_mode) draw_faces(m);
if (wireframe_mode < 2) draw_wireframe(m, color, hole);
glFlush();
|