This is my first post that contains some actual code. I wont provide the entire code for any of the posts, as it will be a spoon feeding. I will off-course give substantial part of it. (And to much extent with any optimizations, leaving them to the imagination of the user :))
We will use DeCasteljau Algorithm algorithm to draw the surface.The similar code using evaluators is available in Red Book Chapter 13.
Before going onto the code please learn a bit of opengl, as i will only explain how to calculate the points.
GLfloat ctrlpoints[4][4][3]; //set the control points as u wish, 4 sets, 4 points each, x, y, z int LOD=20; //increase or decrease this (may be using +/-) to increase number of curves making the surface /* simple linear interpolation between two points in three dimension*/ void lerp (GLfloat dest[], GLfloat a[], GLfloat b[], float t) { dest[0] = a[0] + (b[0]-a[0])*t; dest[1] = a[1] + (b[1]-a[1])*t; dest[2] = a[2] + (b[2]-a[2])*t; } // evaluate a point on a bezier-curve. t goes from 0 to 1.0 void bezier (GLfloat dest[],GLfloat a[],GLfloat b[], GLfloat c[],GLfloat d[], float t) { GLfloat ab[3],bc[3],cd[3],abbc[3],bccd[3]; lerp (ab, a,b,t); // point between a and b lerp (bc, b,c,t); // point between b and c lerp (cd, c,d,t); // point between c and d lerp (abbc, ab,bc,t); // point between ab and bc lerp (bccd, bc,cd,t); // point between bc and cd lerp (dest, abbc,bccd,t); // point on the bezier-curve } /* Given u and v, compute a point on the surface */ void eval(GLfloat dest[],float u,float v,GLfloat pnts[4][4][3]) { GLfloat Q[4][3]; for(int i=0;i<4;i++) { bezier(Q[i],pnts[i][0],pnts[i][1],pnts[i][2],pnts[i][3],u); } bezier(dest,Q[0],Q[1],Q[2],Q[3],v); } /* For orthogonal lines, change we need column vise points This function find transpose of the matrix */ void get_vertical(GLfloat dest[4][4][3]) { for(int i=0;i<4;i++)//ith column { for(int j=0;j<4;j++)//row { for(int k=0;k<3;k++)//elem { dest[i][j][k]=ctrlpoints[j][i][k]; } } } } void display() { /* Intialization etc code here */ /* Compute using algo Plot them using GL_LINE_STRIP to get a smooth line, instead of discrete points */ for(int i=0;i<LOD;i++) { float u = (float)i/(LOD-1); glBegin(GL_LINE_STRIP); for(int j=0;j<LOD;j++) { float v = (float)j/(LOD-1); GLfloat p[3]; eval(p,u,v,ctrlpoints); glVertex3fv(p); } glEnd(); } GLfloat dest[4][4][3]; get_vertical(dest); for(int i=0;i<LOD;i++) { float u = (float)i/(LOD-1); glBegin(GL_LINE_STRIP); for(int j=0;j<LOD;j++) { float v = (float)j/(LOD-1); GLfloat p[3]; eval(p,u,v,dest); glVertex3fv(p); } glEnd(); } /* Swapping buffer etc code goes here */ }