void compute_normal(struct face *f) { /* TODO is this the right direction? I'm bad at rhr */ struct vertex a, b, n; sub_vertex(&a, &f->v[0], &f->v[1]); sub_vertex(&b, &f->v[0], &f->v[2]); cross(&n, &a, &b); normalize3(&n); copy_vertex(&f->n[0], &n); copy_vertex(&f->n[1], &n); copy_vertex(&f->n[2], &n); }
shape_t *copy_shape(const shape_t *s) { shape_t *s2 = new_shape(); for(unsigned i = 0; i < s->num_vertices; ++i) { add_vertex(s2, copy_vertex(s->vertices[i])); } return s2; }
int poly_zclip_if_less(int numverts, const poly_vertex *v, poly_vertex *outv, int paramcount, float clipval) { int prevclipped = (v[numverts - 1].p[0] < clipval); poly_vertex *nextout = outv; int vertnum; /* iterate over vertices */ for (vertnum = 0; vertnum < numverts; vertnum++) { int thisclipped = (v[vertnum].p[0] < clipval); /* if we switched from clipped to non-clipped, interpolate a vertex */ if (thisclipped != prevclipped) interpolate_vertex(nextout++, &v[(vertnum == 0) ? (numverts - 1) : (vertnum - 1)], &v[vertnum], paramcount, clipval); /* if this vertex is not clipped, copy it in */ if (!thisclipped) copy_vertex(nextout++, &v[vertnum], paramcount); /* remember the last state */ prevclipped = thisclipped; } return nextout - outv; }
/* NOTE: This actually reads the copied vertices back from uncached * memory. Could also use the counter/notify mechanism to populate * tmp on the fly as vertices are generated. */ static GLuint copy_dma_verts( radeonContextPtr rmesa, GLfloat (*tmp)[RADEON_MAX_VERTEX_SIZE] ) { GLuint ovf, i; GLuint nr = (rmesa->vb.initial_counter - rmesa->vb.counter) - rmesa->vb.primlist[rmesa->vb.nrprims].start; if (RADEON_DEBUG & DEBUG_VFMT) fprintf(stderr, "%s %d verts\n", __FUNCTION__, nr); switch( rmesa->vb.prim[0] ) { case GL_POINTS: return 0; case GL_LINES: ovf = nr&1; for (i = 0 ; i < ovf ; i++) copy_vertex( rmesa, nr-ovf+i, tmp[i] ); return i; case GL_TRIANGLES: ovf = nr%3; for (i = 0 ; i < ovf ; i++) copy_vertex( rmesa, nr-ovf+i, tmp[i] ); return i; case GL_QUADS: ovf = nr&3; for (i = 0 ; i < ovf ; i++) copy_vertex( rmesa, nr-ovf+i, tmp[i] ); return i; case GL_LINE_STRIP: if (nr == 0) return 0; copy_vertex( rmesa, nr-1, tmp[0] ); return 1; case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_POLYGON: if (nr == 0) return 0; else if (nr == 1) { copy_vertex( rmesa, 0, tmp[0] ); return 1; } else { copy_vertex( rmesa, 0, tmp[0] ); copy_vertex( rmesa, nr-1, tmp[1] ); return 2; } case GL_TRIANGLE_STRIP: ovf = MIN2(nr, 2); for (i = 0 ; i < ovf ; i++) copy_vertex( rmesa, nr-ovf+i, tmp[i] ); return i; case GL_QUAD_STRIP: switch (nr) { case 0: ovf = 0; break; case 1: ovf = 1; break; default: ovf = 2 + (nr&1); break; } for (i = 0 ; i < ovf ; i++) copy_vertex( rmesa, nr-ovf+i, tmp[i] ); return i; default: assert(0); return 0; } }