Tao.Opengl gluNurbsCallback

in my vertex callback function,i can only get an array of length one,just x coordinate,why??i use tao.opengl in .net.i want to get the generated vertex.how can i get every vertex’s x,y,z coordinate??

the second question is how can i let gluNurb generate triangles points ,not quad_strip points???

private const int SPOINTS = 13;
private const int SORDER = 3;
private const int SKNOTS = (SPOINTS + SORDER);
private const int TPOINTS = 3;
private const int TORDER = 3;
private const int TKNOTS = (TPOINTS + TORDER);
private const float SQRT2 = 1.41421356237309504880f;

private static float[] sknots = {
-1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f,
4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 9.0f, 9.0f
};
private static float[] tknots = { 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f };
private static float[/S_NUMPOINTS/, /T_NUMPOINTS/, /4/] controlPoints = {
{
{4.0f, 2.0f, 2.0f, 1.0f},
{4.0f, 1.6f, 2.5f, 1.0f},
{4.0f, 2.0f, 3.0f, 1.0f}
},
{
{5.0f, 4.0f, 2.0f, 1.0f},
{5.0f, 4.0f, 2.5f, 1.0f},
{5.0f, 4.0f, 3.0f, 1.0f}
},
{
{6.0f, 5.0f, 2.0f, 1.0f},
{6.0f, 5.0f, 2.5f, 1.0f},
{6.0f, 5.0f, 3.0f, 1.0f}
},
{
{SQRT2 * 6.0f, SQRT2 * 6.0f, SQRT2 * 2.0f, SQRT2},
{SQRT2 * 6.0f, SQRT2 * 6.0f, SQRT2 * 2.5f, SQRT2},
{SQRT2 * 6.0f, SQRT2 * 6.0f, SQRT2 * 3.0f, SQRT2}
},
{
{5.2f, 6.7f, 2.0f, 1.0f},
{5.2f, 6.7f, 2.5f, 1.0f},
{5.2f, 6.7f, 3.0f, 1.0f}
},
{
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 2.0f, SQRT2},
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 2.5f, SQRT2},
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 3.0f, SQRT2}
},
{
{4.0f, 5.2f, 2.0f, 1.0f},
{4.0f, 4.6f, 2.5f, 1.0f},
{4.0f, 5.2f, 3.0f, 1.0f}
},
{
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 2.0f, SQRT2},
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 2.5f, SQRT2},
{SQRT2 * 4.0f, SQRT2 * 6.0f, SQRT2 * 3.0f, SQRT2}
},
{
{2.8f, 6.7f, 2.0f, 1.0f},
{2.8f, 6.7f, 2.5f, 1.0f},
{2.8f, 6.7f, 3.0f, 1.0f}
},
{
{SQRT2 * 2.0f, SQRT2 * 6.0f, SQRT2 * 2.0f, SQRT2},
{SQRT2 * 2.0f, SQRT2 * 6.0f, SQRT2 * 2.5f, SQRT2},
{SQRT2 * 2.0f, SQRT2 * 6.0f, SQRT2 * 3.0f, SQRT2}
},
{
{2.0f, 5.0f, 2.0f, 1.0f},
{2.0f, 5.0f, 2.5f, 1.0f},
{2.0f, 5.0f, 3.0f, 1.0f}
},
{
{3.0f, 4.0f, 2.0f, 1.0f},
{3.0f, 4.0f, 2.5f, 1.0f},
{3.0f, 4.0f, 3.0f, 1.0f}
},
{
{4.0f, 2.0f, 2.0f, 1.0f},
{4.0f, 1.6f, 2.5f, 1.0f},
{4.0f, 2.0f, 3.0f, 1.0f}
}
};
private static Glu.GLUnurbs nurb;
private static FileStream aFile = new FileStream(“vertices.txt”, FileMode.OpenOrCreate);
private static StreamWriter sr = new StreamWriter(aFile);
private static void begin(int which)
{
switch (which)
{
case Gl.GL_LINE:
Console.WriteLine(“GL_Line”);
sr.WriteLine(“line”);
break;
case Gl.GL_TRIANGLE_FAN:
Console.WriteLine(“GL_TRIANGLE_FAN”);
sr.WriteLine(“GL_TRIANGLE_FAN”);
break;
case Gl.GL_TRIANGLE_STRIP:
Console.WriteLine(“GL_TRIANGLE_STRIP”);
sr.WriteLine(“GL_TRIANGLE_STRIP”);
break;
case Gl.GL_TRIANGLES:
Console.WriteLine(“GL_TRIANGLES”);
sr.WriteLine(“GL_TRIANGLES”);
break;
case Gl.GL_QUAD_STRIP:
Console.WriteLine(“GL_QUAD_STRIP”);
sr.WriteLine(“GL_QUAD_STRIP”);
break;
case Gl.GL_QUADS:
Console.WriteLine(“GL_QUADS”);
sr.WriteLine(“GL_QUADS”);
break;

}
sr.Flush();
}
private static void end()
{
int a = 0;
}
private static void vertex(float[] vertexData)
{
Console.WriteLine(vertexData[0]);

}
private static void error(int type)
{
int A = 0;
}
private static void N(int type)
{
int A = 0;
}
private static void Init()
{
float[] materialAmbient = { 1.0f, 1.0f, 1.0f, 1.0f };
float[] materialDiffuse = { 1.0f, 0.2f, 1.0f, 1.0f };
float[] materialSpecular ={ 1.0f, 1.0f, 1.0f, 1.0f };
float[] materialShininess={ 50.0f };
float[] light0Position = { 1.0f, 0.1f, 1.0f, 0.0f };
float[] light1Position = { -1.0f, 0.1f, 1.0f, 0.0f };
float[] lightModelAmbient={ 0.3f, 0.3f, 0.3f, 1.0f };

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, materialAmbient);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, materialDiffuse);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, materialSpecular);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, materialShininess);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, light0Position);
Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, light1Position);
Gl.glLightModelfv(Gl.GL_LIGHT_MODEL_AMBIENT, lightModelAmbient);

Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glEnable(Gl.GL_LIGHT1);
Gl.glDepthFunc(Gl.GL_LESS);
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glEnable(Gl.GL_AUTO_NORMAL);

nurb = Glu.gluNewNurbsRenderer();
Glu.gluNurbsProperty(nurb, Glu.GLU_SAMPLING_TOLERANCE, 50.0f);
Glu.gluNurbsProperty(nurb, Glu.GLU_DISPLAY_MODE, Glu.GLU_OUTLINE_POLYGON);
Glu.gluNurbsProperty(nurb, Glu.GLU_NURBS_MODE, Glu.GLU_NURBS_TESSELLATOR);
Glu.gluNurbsCallback(nurb, Glu.GLU_NURBS_BEGIN, new Glu.NurbsBeginCallback(begin));
Glu.gluNurbsCallback(nurb, Glu.GLU_NURBS_END, new Glu.NurbsEndCallback(end));
Glu.gluNurbsCallback(nurb, Glu.GLU_NURBS_VERTEX, new Glu.NurbsVertexCallback(vertex));
Glu.gluNurbsCallback(nurb, Glu.GLU_NURBS_ERROR, new Glu.NurbsErrorCallback(error));

string tempStr = Glu.gluGetString(Glu.GLU_VERSION);
}

private static void Display()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glPushMatrix();
Gl.glTranslatef(4.0f, 4.5f, 2.5f);
Gl.glRotatef(220.0f, 1.0f, 0.0f, 0.0f);
Gl.glRotatef(115.0f, 0.0f, 1.0f, 0.0f);
Gl.glTranslatef(-4.0f, -4.5f, -2.5f);

Glu.gluBeginSurface(nurb);
Glu.gluNurbsSurface(nurb, SKNOTS, sknots, TKNOTS, tknots, 4 * TPOINTS, 4, controlPoints, SORDER, TORDER, Gl.GL_MAP2_VERTEX_4);
Glu.gluEndSurface(nurb);
Gl.glPopMatrix();
Gl.glFlush();
}

private static void Keyboard(byte key, int x, int y)
{
switch (key)
{
case 27:
Environment.Exit(0);
break;
}
}

private static void Reshape(int w, int h)
{
Gl.glViewport(0, 0, w, h);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Gl.glFrustum(-1.0, 1.0, -1.5, 0.5, 0.8, 10.0);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Glu.gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.0, 6.0, -3.0, 2.0);
}
static void Main(string[] args)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_SINGLE | Glut.GLUT_RGB | Glut.GLUT_DEPTH);
Glut.glutCreateWindow(“Nurbs”);
Init();
Glut.glutDisplayFunc(new Glut.DisplayCallback(Display));
Glut.glutKeyboardFunc(new Glut.KeyboardCallback(Keyboard));
Glut.glutReshapeFunc(new Glut.ReshapeCallback(Reshape));
Glut.glutMainLoop();
}