+ // calculate control points for this row by collapsing the 3
+ // rows of control points to one row using py
+ py = (float)y / (float)(tesselationheight*2);
+ // calculate quadratic spline weights for py
+ a = ((1.0f - py) * (1.0f - py));
+ b = ((1.0f - py) * (2.0f * py));
+ c = (( py) * ( py));
+ for (component = 0;component < numcomponents;component++)
+ {
+ temp[0][component] = cp[0][0][component] * a + cp[1][0][component] * b + cp[2][0][component] * c;
+ temp[1][component] = cp[0][1][component] * a + cp[1][1][component] * b + cp[2][1][component] * c;
+ temp[2][component] = cp[0][2][component] * a + cp[1][2][component] * b + cp[2][2][component] * c;
+ }
+ // fetch a pointer to the beginning of the output vertex row
+ v = (float *)((unsigned char *)outputvertices + ((k * tesselationheight + y) * outputwidth + l * tesselationwidth) * outputstride);
+ // for each column of the row...
+ for (x = 0;x <= (tesselationwidth*2);x++)
+ {
+ // calculate point based on the row control points
+ px = (float)x / (float)(tesselationwidth*2);
+ // calculate quadratic spline weights for px
+ // (could be precalculated)
+ a = ((1.0f - px) * (1.0f - px));
+ b = ((1.0f - px) * (2.0f * px));
+ c = (( px) * ( px));
+ for (component = 0;component < numcomponents;component++)
+ v[component] = temp[0][component] * a + temp[1][component] * b + temp[2][component] * c;
+ // advance to next output vertex using outputstride
+ // (the next vertex may not be directly following this
+ // one, as this may be part of a larger structure)
+ v = (float *)((unsigned char *)v + outputstride);
+ }