void display(void) { GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; GLfloat edgePt[5][2] = /* counter clockwise */ {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}; GLfloat curvePt[4][2] = /* clockwise */ {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}}; GLfloat curveKnots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; GLfloat pwlPt[4][2] = /* clockwise */ {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(330.0, 1.,0.,0.); glScalef (0.5, 0.5, 0.5); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3); gluBeginTrim (theNurb); gluPwlCurve (theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (theNurb); gluBeginTrim (theNurb); gluNurbsCurve (theNurb, 8, curveKnots, 2, &curvePt[0][0], 4, GLU_MAP1_TRIM_2); gluPwlCurve (theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (theNurb); gluEndSurface(theNurb); glPopMatrix(); glFlush(); }
void ReDraw(void) { glColor3ub(0,0,220); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glRotatef(330.0f, 1.0f,0.0f,0.0f); // 定义NURBS曲线 gluBeginCurve(pNurb); gluNurbsCurve(pNurb, // 定义NURBS对象 8, // knot中的结点数目 Knots, // knots数组 3, // 相邻两个曲线控制点之间的偏移量 &ctrlPoints[0][0], // 指向控制点数组的指针 4, // 曲线的阶数 GL_MAP1_VERTEX_3); // 曲线的类型 gluEndCurve(pNurb); DrawPoints(); glPopMatrix(); glutSwapBuffers(); }
void display(void) { char buffer[256]; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* keep in mind that `D` and `E` are simply pointers to the corresponding control points of `spline`. */ for (i = 0; i < 3; i++) { D[i] = A[i] + t*v[i]; E[i] = C[i] + t*w[i]; } ts_bspline_set_control_points(&spline, ctrlp, NULL); /* draw spline */ glColor3f(1.0, 1.0, 1.0); glLineWidth(3); gluBeginCurve(theNurb); gluNurbsCurve( theNurb, (GLint)ts_bspline_num_knots(&spline), knots, (GLint)ts_bspline_dimension(&spline), ctrlp, (GLint)ts_bspline_order(&spline), GL_MAP1_VERTEX_3 ); gluEndCurve(theNurb); /* draw control points */ glColor3f(1.0, 0.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); for (i = 0; i < ts_bspline_num_control_points(&spline); i++) glVertex3fv(&ctrlp[i * ts_bspline_dimension(&spline)]); glEnd(); /* draw B */ glColor3f(0.0, 0.0, 1.0); glBegin(GL_POINTS); glVertex3fv(B); glEnd(); /* display t */ sprintf(buffer, "t: %.2f", t); displayText(-.2f, 1.2f, 0.0, 1.0, 0.0, buffer); glutSwapBuffers(); glutPostRedisplay(); t += 0.001f; if (t > 1.f) { t = 0.f; } }
void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw spline glColor3f(1.0, 1.0, 1.0); glLineWidth(3); gluBeginCurve(theNurb); gluNurbsCurve( theNurb, spline.n_knots, spline.knots, spline.dim, spline.ctrlp, spline.order, GL_MAP1_VERTEX_3 ); gluEndCurve(theNurb); // draw control points glColor3f(1.0, 0.0, 0.0); glPointSize(5.0); float j=0; size_t i; glBegin(GL_POINTS); for (i = 0; i < spline.n_ctrlp; i++) { j+=1.0/n_ctrlp; glColor3f(0.0, j, 0.0); glVertex3fv(&spline.ctrlp[i * spline.dim]); } glEnd(); // draw evaluation glColor3f(0.0, 0.0, 1.0); glPointSize(5.0); tsDeBoorNet net; ts_bspline_evaluate(&spline, u, &net); glBegin(GL_POINTS); glVertex3fv(net.result); glEnd(); ts_deboornet_free(&net); u += 0.001; if (u > 4.f) { u = 0.f; } glutSwapBuffers(); glutPostRedisplay(); }
void Sample_12_8::draw() { int i, j; GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; GLfloat edgePt[5][2] = /* counter clockwise */ {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}; GLfloat curvePt[4][2] = /* clockwise */ {{0.25, 0.5}, {0.25, 0.75}, {0.75, 0.75}, {0.75, 0.5}}; GLfloat curveKnots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; GLfloat pwlPt[4][2] = /* clockwise */ {{0.75, 0.5}, {0.5, 0.25}, {0.25, 0.5}}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(330.0, 1.,0.,0.); glScalef (0.5, 0.5, 0.5); gluBeginSurface(m_theNurb); gluNurbsSurface(m_theNurb, 8, knots, 8, knots, 4 * 3, 3, &m_ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3); gluBeginTrim (m_theNurb); gluPwlCurve (m_theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (m_theNurb); gluBeginTrim (m_theNurb); gluNurbsCurve (m_theNurb, 8, curveKnots, 2, &curvePt[0][0], 4, GLU_MAP1_TRIM_2); gluPwlCurve (m_theNurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (m_theNurb); gluEndSurface(m_theNurb); if (m_showPoints) { glPointSize(5.0); glDisable(GL_LIGHTING); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { glVertex3f(m_ctlpoints[i][j][0], m_ctlpoints[i][j][1], m_ctlpoints[i][j][2]); } } glEnd(); glEnable(GL_LIGHTING); } glPopMatrix(); }
void display(void) { size_t i; tsBSpline buckled; tsReal *ctrlp, *knots; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ts_bspline_buckle(&spline, b, &buckled, NULL); /* draw buckled */ ts_bspline_control_points(&buckled, &ctrlp, NULL); ts_bspline_knots(&buckled, &knots, NULL); glColor3f(1.0, 1.0, 1.0); glLineWidth(3); gluBeginCurve(theNurb); gluNurbsCurve( theNurb, (GLint)ts_bspline_num_knots(&buckled), knots, (GLint)ts_bspline_dimension(&buckled), ctrlp, (GLint)ts_bspline_order(&buckled), GL_MAP1_VERTEX_3 ); gluEndCurve(theNurb); /* draw control points */ glColor3f(1.0, 0.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); for (i = 0; i < ts_bspline_num_control_points(&buckled); i++) glVertex3fv(&ctrlp[i * ts_bspline_dimension(&buckled)]); glEnd(); ts_bspline_free(&buckled); free(ctrlp); free(knots); b -= 0.001f; if (b < 0.f) b = 1.f; glutSwapBuffers(); glutPostRedisplay(); }
/* Execute a bgn/endtrim pair for the given trim curve structure. */ void dotrim(TrimCurve *trim_curve) { int i; gluBeginTrim(nurbsflag); for (i=0; i<trim_curve->pieces; i++) { if (trim_curve->trim[i].type == PWL) { gluPwlCurve(nurbsflag, trim_curve->trim[i].points, &trim_curve->trim[i].point[0][0], 2, GLU_MAP1_TRIM_2); } else { gluNurbsCurve(nurbsflag, ELEMENTS(trimknots),trimknots, 2,&trim_curve->trim[i].point[0][0], trim_curve->trim[i].points, GLU_MAP1_TRIM_2); } } gluEndTrim(nurbsflag); }
void render_scene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Render trimmed surface */ gluBeginSurface(nurb); gluNurbsSurface(nurb, 8, knots, 8, knots, 4*3, 3, &ctlpoints[0][0][0], 4, 4, GLU_MAP2_VERTEX_3); gluBeginTrim(nurb); gluPwlCurve(nurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim(nurb); gluBeginTrim(nurb); gluNurbsCurve(nurb, 8, curveKnots, 2, &curvePt[0][0], 4, GLU_MAP1_TRIM_2); gluPwlCurve (nurb, 3, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim(nurb); gluEndSurface(nurb); /* Flush all drawings */ glFlush(); }
void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* glLoadIdentity(); */ glColor3f(0.,0.,0.); glPushMatrix(); glScalef(1.3, 1.3, 1.); gluBeginCurve(pNurb2); gluNurbsCurve(pNurb2, nKnots2, Knots2, kStride, &pointsWeights2[flyingboom][0][0], order2, GL_MAP1_VERTEX_4); gluEndCurve(pNurb2); // Draw the control points glPointSize(3.0f); glColor3f(1.,0.,0.); glBegin(GL_POINTS); for(i = 0; i < NPOINTS2; i++) glVertex3fv(pointsWeights2[flyingboom][i]); glEnd(); glPointSize(5.0f); glColor3f(0.,0.,1.); glBegin(GL_POINTS); for(i = 1; i < NPOINTS2; i += 2) glVertex3fv(pointsWeights2[flyingboom][i]); glEnd(); glColor3f(0., 1., 0.); glBegin(GL_POINTS); glVertex3fv(pointsWeights2[flyingboom][0]); if (flyingboom == NUMBOOMS - 1) glVertex3f(0., 0., 0.); glEnd(); glPopMatrix(); glFlush(); }
void render_scene() { int count=0; int u=0; glClear(GL_COLOR_BUFFER_BIT); /* Curve color */ glColor4f(0.0f, 1.0f, 0.0f, 1.0f); /* tells GLU we are going to describe a nurbs curve */ gluBeginCurve(mynurbs); /* send it the definition and pointers to cv and knot data */ gluNurbsCurve(mynurbs, numknots, knots, stride, cvs, order, GLU_MAP1_VERTEX_3); /* thats all... */ gluEndCurve(mynurbs); /* Control points color */ glColor4f(0.0f, 0.0f, 1.0f, 1.0f); /* Enable vertex array */ glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, cvs); /* render the control vertex positions */ glDrawArrays(GL_POINTS, 0, cvcount); glDisableClientState(GL_VERTEX_ARRAY); /* Flush all drawings */ glFlush(); /* Update knots */ for (u=0; u<cvcount; u++) { cvs[count++]=0; cvs[count++]=cos(5.2f*sqrt(u*u)+frame*0.01f)*0.5f; cvs[count++]=sin(10.0f*sqrt(u*u)+frame*0.013f)*0.5f; } frame++; }
// Called to draw scene void RenderScene(void) { // Draw in Blue glColor3ub(0,0,220); // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Save the modelview matrix stack glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Rotate the mesh around to make it easier to see glRotatef(330.0f, 1.0f,0.0f,0.0f); // Render the NURB // Begin the NURB definition gluBeginCurve(pNurb); // Evaluate the surface gluNurbsCurve(pNurb, 8, Knots, 3, &ctrlPoints[0][0], 4, GL_MAP1_VERTEX_3); // Done with surface gluEndCurve(pNurb); // Show the control points DrawPoints(); // Restore the modelview matrix glPopMatrix(); // Dispalay the image glutSwapBuffers(); }
void display(void){ int i; glClear(GL_COLOR_BUFFER_BIT); switch(spline){ case BEZIER: glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, nVertices, &vertices[0][0]); glBegin(GL_LINE_STRIP); for (i = 0; i <= 30; i++){ glEvalCoord1f((GLfloat) i/30.0); } glEnd(); break; case NURBS: gluBeginCurve(nc); gluNurbsCurve(nc, nNos, nos, 3, &vertices[0][0], 4, GL_MAP1_VERTEX_3); gluEndCurve(nc); break; } glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_LINE_STRIP); for (i = 0; i < nVertices; i++) glVertex3fv(&vertices[i][0]); glEnd(); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < nVertices; i++) glVertex3fv(&vertices[i][0]); glEnd(); glColor3f(1.0, 1.0, 1.0); glFlush(); glutSwapBuffers(); }
void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); tsBSpline draw; if (drawBeziers) ts_bspline_to_beziers(&spline, &draw); else ts_bspline_copy(&spline, &draw); glColor3f(1.0, 1.0, 1.0); glLineWidth(3); gluBeginCurve(theNurb); gluNurbsCurve( theNurb, draw.n_knots, draw.knots, draw.dim, draw.ctrlp, draw.order, GL_MAP1_VERTEX_3 ); gluEndCurve(theNurb); ts_bspline_free(&draw); // draw control points glColor3f(1.0, 0.0, 0.0); glPointSize(5.0); size_t i; glBegin(GL_POINTS); for (i = 0; i < spline.n_ctrlp; i++) glVertex3fv(&spline.ctrlp[i * spline.dim]); glEnd(); glutSwapBuffers(); glutPostRedisplay(); }
/* nurb:Curve (knotsArray, controlArray, type) -> nurb */ static int luaglu_nurbs_curve(lua_State *L) { LuaGLUnurb *lnurb=luaglu_checknurb(L,1); GLint ptsCount=0; GLint knotCount=0; GLfloat *knots; GLint stride; GLfloat *points; GLint order; int size=1; GLenum e; e = luaglu_get_gl_enum(L, 4); switch(e) { case GL_MAP1_INDEX: case GL_MAP2_INDEX: case GL_MAP1_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_1: size = 1; break; case GLU_MAP1_TRIM_2: case GL_MAP1_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_2: size = 2; break; case GLU_MAP1_TRIM_3: case GL_MAP1_VERTEX_3: case GL_MAP2_VERTEX_3: case GL_MAP1_NORMAL: case GL_MAP2_NORMAL: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP2_TEXTURE_COORD_3: size = 3; break; case GL_MAP1_VERTEX_4: case GL_MAP2_VERTEX_4: case GL_MAP1_COLOR_4: case GL_MAP2_COLOR_4: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP2_TEXTURE_COORD_4: size = 4; break; } knotCount=luagl_get_arrayf(L, 2, &knots); ptsCount=luagl_get_arrayf(L, 3, &points); ptsCount/=size; stride=size; order=knotCount-ptsCount; if(order<1) { LUAGL_DELETE_ARRAY(knots); LUAGL_DELETE_ARRAY(points); luaL_error(L,"incorrect order (<1)"); } gluNurbsCurve (lnurb->nurb,knotCount,knots,stride,points,order,e); LUAGL_DELETE_ARRAY(knots); LUAGL_DELETE_ARRAY(points); lua_pushvalue(L,1); return 1; }
void ON_GL( int dim, int is_rat, int nurb_order, int cv_count, const double* knot_vector, int cv_stride, const double* cv, GLUnurbsObj* nobj, GLenum type, int bPermitKnotScaling, double* knot_scale, double xform[][4] ) { ON_BOOL32 bCallgluBeginEndCurve = false; int i; GLint nknots = nurb_order + cv_count; // GL knot count = TL knot count + 2 GLfloat* knot = (GLfloat*)onmalloc( nknots*sizeof(*knot) ); ON_GL( nurb_order, cv_count, knot_vector, knot, bPermitKnotScaling, knot_scale ); // control vertices //const int cv_size = (is_rat) ? dim+1: dim; GLint stride = cv_stride; GLfloat* ctlarray = (GLfloat*)onmalloc( stride*cv_count*sizeof(*ctlarray) ); for ( i = 0; i < cv_count; i++ ) { GetGLCV( dim, is_rat, cv + i*cv_stride, xform, ctlarray + stride*i ); } GLint order = nurb_order; switch(type) { case 0: { switch ( dim ) { case 2: // must be a GLU_MAP1_TRIM_2/3 type = ( is_rat ) ? GLU_MAP1_TRIM_3 // rational 2d trim uses homogeneous coords : GLU_MAP1_TRIM_2; // non-rational 2d trim uses euclidean coords break; case 3: // must be a GLU_MAP1_VERTEX_3/4 type = ( is_rat ) ? GL_MAP1_VERTEX_4 // rational 3d curve uses homogeneous coords : GL_MAP1_VERTEX_3; // non-rational 3d curve used euclidean coords bCallgluBeginEndCurve = true; break; } } break; case GLU_MAP1_TRIM_2: case GLU_MAP1_TRIM_3: // make sure type matches rational flag type = ( is_rat ) ? GLU_MAP1_TRIM_3 // rational 2d trim uses homogeneous coords : GLU_MAP1_TRIM_2; // non-rational 2d trim uses euclidean coords break; case GL_MAP1_VERTEX_3: case GL_MAP1_VERTEX_4: // make sure type matches rational flag type = ( is_rat ) ? GL_MAP1_VERTEX_4 // rational 3d curve uses homogeneous coords : GL_MAP1_VERTEX_3; // non-rational 3d curve used euclidean coords bCallgluBeginEndCurve = true; break; } if ( bCallgluBeginEndCurve ) gluBeginCurve(nobj); gluNurbsCurve( nobj, nknots, knot, stride, ctlarray, order, type ); if ( bCallgluBeginEndCurve ) gluEndCurve(nobj); onfree( ctlarray ); onfree( knot ); }
void SoNurbsSurface::GLRender(SoGLRenderAction *action) // //////////////////////////////////////////////////////////////////////// { // First see if the object is visible and should be rendered now if (! shouldGLRender(action)) return; const SoCoordinateElement *ce = SoCoordinateElement::getInstance(action->getState()); GLfloat *sKnots, *tKnots, *dstCoords; GLenum type; float *fKnots; int32_t nCoords, uOffset, vOffset; int32_t nsKnots, ntKnots, nsCoords, ntCoords; int32_t nDstCoords; int32_t sOffset, tOffset; int i, j; // Check for 0 control points nCoords = ce->getNum(); if (nCoords == 0) return; // Make sure the first current material is sent to GL SoMaterialBundle mb(action); mb.sendFirst(); // // Find the number of steps required for object space tessellation and // the pixel tolerance used for screen space tessellation. // float val = SoComplexityElement::get(action->getState()); if (val < 0.0) val = 0.0; if (val > 1.0) val = 1.0; int steps; if (val < 0.10) steps = 2; else if (val < 0.25) steps = 3; else if (val < 0.40) steps = 4; else if (val < 0.55) steps = 5; else steps = (int)(powf(val, 3.32)*28) + 2; float pixTolerance = 104.0*val*val - 252.0*val + 150; // // If the surface is being cached, or if the tessellation is in object // space, use the software NURBS library. Create a software NURBS // rendering class and use it to make nurbs rendering calls. Since // the software NURBS library generates triangles, texture mapping // will happen automatically without having to render a separate // texture surface. // if (SoComplexityTypeElement::get(action->getState()) == SoComplexityTypeElement::OBJECT_SPACE) { _SoNurbsGLRender *GLRender = new _SoNurbsGLRender(); // // Set the sampling to be constant across the surface with the // tessellation to be 'steps' across the S and T parameters // GLRender->setnurbsproperty( N_T2D, N_SAMPLINGMETHOD, N_FIXEDRATE ); GLRender->setnurbsproperty( N_V3D, N_SAMPLINGMETHOD, N_FIXEDRATE ); GLRender->setnurbsproperty( N_V3DR, N_SAMPLINGMETHOD, N_FIXEDRATE ); GLRender->setnurbsproperty( N_T2D, N_S_STEPS, steps); GLRender->setnurbsproperty( N_T2D, N_T_STEPS, steps); GLRender->setnurbsproperty( N_V3D, N_S_STEPS, steps); GLRender->setnurbsproperty( N_V3D, N_T_STEPS, steps); GLRender->setnurbsproperty( N_V3DR, N_S_STEPS, steps); GLRender->setnurbsproperty( N_V3DR, N_T_STEPS, steps); // Determine whether a texture coordinate surface must be generated SbBool doTextures = SoGLTextureEnabledElement::get(action->getState()); // Draw the surface drawNURBS (GLRender, action->getState(), doTextures); delete GLRender; return; } if (SoDrawStyleElement::get(action->getState()) == SoDrawStyleElement::POINTS) { // // Render the control points of the surface. Rendering the points // of the surface would be very slow, as the Software NURBS library // would have to be used, and because of the view dependent // tessellation, points would not necessarily remain visible. // glBegin(GL_POINTS); if (ce->is3D()) { for (i=0; i<nCoords; i++) { const SbVec3f & coords3 = ce->get3((int)i); glVertex3f ((GLfloat)(coords3[0]), (GLfloat)(coords3[1]), (GLfloat)(coords3[2])); } } else { for (i=0; i<nCoords; i++) { const SbVec4f & coords4 = ce->get4((int)i); glVertex4f ((GLfloat)(coords4[0]), (GLfloat)(coords4[1]), (GLfloat)(coords4[2]), (GLfloat)(coords4[3])); } } glEnd(); return; } // // Render the NURBS surface using the GLU. // GLUnurbsObj *nurbsObj = gluNewNurbsRenderer(); switch (SoDrawStyleElement::get(action->getState())) { case SoDrawStyleElement::FILLED: gluNurbsProperty (nurbsObj, (GLenum)GLU_DISPLAY_MODE, GLU_FILL); break; case SoDrawStyleElement::LINES: gluNurbsProperty (nurbsObj, (GLenum)GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON); break; } gluNurbsProperty (nurbsObj, (GLenum)GLU_SAMPLING_TOLERANCE, (GLfloat)pixTolerance); // // Collect the control points and knot vectors into an array suitable // for sending to the GL. The control points and knot vectors must be // converted to double precision so that they can be passed to the // GL NURBS routines. // GLfloat *dCoords, *duKnots, *dvKnots; if (ce->is3D()) { dCoords = (GLfloat *)new GLfloat[3*nCoords]; for (i=0; i<nCoords; i++) { const SbVec3f &c3 = ce->get3((int)i); dCoords[3*i] = (GLfloat)c3[0]; dCoords[3*i+1] = (GLfloat)c3[1]; dCoords[3*i+2] = (GLfloat)c3[2]; } uOffset = 3; type = GL_MAP2_VERTEX_3; } else { dCoords = (GLfloat *)new GLfloat[4*nCoords]; for (i=0; i<nCoords; i++) { const SbVec4f &c4 = ce->get4((int)i); dCoords[4*i] = (GLfloat)c4[0]; dCoords[4*i+1] = (GLfloat)c4[1]; dCoords[4*i+2] = (GLfloat)c4[2]; dCoords[4*i+3] = (GLfloat)c4[3]; } uOffset = 4; type = GL_MAP2_VERTEX_4; } vOffset = uOffset * numUControlPoints.getValue(); fKnots = (float *)uKnotVector.getValues(0); duKnots = (GLfloat *)new GLfloat[uKnotVector.getNum()]; for (i=0; i<uKnotVector.getNum(); i++) duKnots[i] = (GLfloat)fKnots[i]; fKnots = (GLfloat *)vKnotVector.getValues(0); dvKnots = (GLfloat *)new GLfloat[vKnotVector.getNum()]; for (i=0; i<vKnotVector.getNum(); i++) dvKnots[i] = (GLfloat)fKnots[i]; // Texture mapping. If doTextures == TRUE // we are drawing textures. If the textureCoordinateBinding is // DEFAULT, we have to build a default NURBS surface for the texture // coordinates, otherwise we use the texture coordinates in the texture // element. // If there is a software texture function defined, then we have to // create a texture nurb surface with the same number of points and // knots as the original surface, and call the texture coordinate function // at each vertex. SbBool doTextures = SoGLTextureEnabledElement::get(action->getState()); if(doTextures) { switch (SoTextureCoordinateElement::getType(action->getState())) { // software texture functions case SoTextureCoordinateElement::FUNCTION: { // generate S and T coords from U and V coords SbVec3f coord; SbVec2f stCoord; int offset; SoTextureCoordinateBundle tb(action, TRUE); nsCoords = numUControlPoints.getValue(); ntCoords = numVControlPoints.getValue(); sKnots = duKnots; tKnots = dvKnots; nsKnots = uKnotVector.getNum(); ntKnots = vKnotVector.getNum(); nDstCoords = nsCoords * ntCoords; dstCoords = (GLfloat *)new GLfloat[nDstCoords * 2]; for(int v = 0; v < ntCoords; v++) { for(int u = 0; u < nsCoords; u++) { if (ce->is3D()) { offset = 3 * (v * (int)nsCoords + u); coord[0] = dCoords[offset + 0]; coord[1] = dCoords[offset + 1]; coord[2] = dCoords[offset + 2]; } else { offset = 4 * (v * (int)nsCoords + u); coord[0] = dCoords[offset + 0] / dCoords[offset + 3]; coord[1] = dCoords[offset + 1] / dCoords[offset + 3]; coord[2] = dCoords[offset + 2] / dCoords[offset + 3]; } const SbVec4f &tc = tb.get(coord, SbVec3f(0.0, 1.0, 0.0)); dstCoords[(v * (int)nsCoords + u) * 2 + 0] = tc[0]; dstCoords[(v * (int)nsCoords + u) * 2 + 1] = tc[1]; } } break; } // texture coordinates defined from texture node case SoTextureCoordinateElement::EXPLICIT: // get texture coordinates from texture node const SoTextureCoordinateElement *te = SoTextureCoordinateElement::getInstance(action->getState()); int32_t nstCoords = te->getNum(); if (nstCoords < 1) { // Default texture coordinates are computed by defining // a bezier surface that is defined in the same valid // parameter space as the geometric surface. The valid // parameter space is defined based on the order and knot // vector. The coordinates go from 0 to one and the knot // vectors span the valid range of the geometric surface. // The knot vectors default to 0 and 1 in the event of bogus // input data. int uOrder, vOrder; GLfloat sKnotVal1, sKnotVal2, tKnotVal1, tKnotVal2; uOrder = uKnotVector.getNum() - numUControlPoints.getValue(); vOrder = vKnotVector.getNum() - numVControlPoints.getValue(); if ((uOrder > 0) && (uOrder < uKnotVector.getNum())) sKnotVal1 = duKnots[uOrder-1]; else sKnotVal1 = 0; if ((uOrder > 0) && (uOrder < uKnotVector.getNum())) sKnotVal2 = duKnots[uKnotVector.getNum()-uOrder]; else sKnotVal2 = 1; if ((vOrder > 0) && (vOrder < vKnotVector.getNum())) tKnotVal1 = dvKnots[vOrder-1]; else tKnotVal1 = 0; if ((vOrder > 0) && (vOrder < vKnotVector.getNum())) tKnotVal2 = dvKnots[vKnotVector.getNum()-vOrder]; else tKnotVal2 = 1; // do a linear 2x2 array nsKnots = 4; ntKnots = 4; sKnots = (GLfloat *)new GLfloat[4]; tKnots = (GLfloat *)new GLfloat[4]; sKnots[0] = sKnots[1] = sKnotVal1; tKnots[0] = tKnots[1] = tKnotVal1; sKnots[2] = sKnots[3] = sKnotVal2; tKnots[2] = tKnots[3] = tKnotVal2; // allocate a 2 x 2 array of GLfloat[2]'s nsCoords = 2; ntCoords = 2; nDstCoords = nsCoords * ntCoords * 2; dstCoords = (GLfloat *)new GLfloat[nDstCoords]; for(i = 0; i < 2; i++) { for(j = 0; j < 2; j++) { dstCoords[(i * 2 + j) * 2 + 0] = j; dstCoords[(i * 2 + j) * 2 + 1] = i; } } } else { // get knot vectors from this node nsKnots = sKnotVector.getNum(); fKnots = (float *)sKnotVector.getValues(0); sKnots = (GLfloat *)new GLfloat[nsKnots]; for (i=0; i < nsKnots; i++) sKnots[i] = (GLfloat)fKnots[i]; ntKnots = tKnotVector.getNum(); fKnots = (float *)tKnotVector.getValues(0); tKnots = (GLfloat *)new GLfloat[ntKnots]; for (i=0; i < ntKnots; i++) tKnots[i] = (GLfloat)fKnots[i]; nsCoords = numSControlPoints.getValue(); ntCoords = numTControlPoints.getValue(); nDstCoords = 2 * nstCoords; dstCoords = (GLfloat *)new GLfloat[nDstCoords]; for(i = 0; i < nstCoords; i++) { const SbVec2f &tc2 = te->get2(i); dstCoords[2*i] = (GLfloat)tc2[0]; dstCoords[2*i+1] = (GLfloat)tc2[1]; } } break; } sOffset = 2; tOffset = sOffset * nsCoords; } // // Draw the NURBS surface. Begin the surface. Then load the texture // map as a nurbs surface. Then, draw the geometric surface followed // by all of its trim curves. Then, end the surface. // glEnable(GL_AUTO_NORMAL); // Get one camera based element so that this node will be registered // with the cache. If the camera changes, this element will cause // the cache to be blown for this node and the nurbs surface will be // regenerated. SbMatrix vMat = SoViewingMatrixElement::get (action->getState()); SbMatrix mMat = SoModelMatrixElement::get (action->getState()); // Begin the surface. gluBeginSurface(nurbsObj); // Draw the texture surface if(doTextures) { // send down nurbs surface, then free memory gluNurbsSurface(nurbsObj, (GLint)nsKnots, sKnots, (GLint)ntKnots, tKnots, (GLint)sOffset, (GLint)tOffset, dstCoords, (GLint)(nsKnots - nsCoords), (GLint)(ntKnots - ntCoords), GL_MAP2_TEXTURE_COORD_2); // delete knots if not sharing them with the surface description // (in the case of software texture coordinates only) if(sKnots != duKnots) { delete [] sKnots; delete [] tKnots; } delete [] dstCoords; } gluNurbsSurface (nurbsObj, (GLint)(uKnotVector.getNum()), duKnots, (GLint)(vKnotVector.getNum()), dvKnots, (GLint)uOffset, (GLint)vOffset, dCoords, (GLint)(uKnotVector.getNum() - numUControlPoints.getValue()), (GLint)(vKnotVector.getNum() - numVControlPoints.getValue()), type); // // Get all of the trim curves and use them to trim the surface. // SoProfile *profile; const SoNodeList &trimNodes = SoProfileElement::get(action->getState()); SbBool haveTrim = FALSE; float *trimCoords, *trimKnots; int32_t numTrimCoords, numKnots, offset; int numTrims = trimNodes.getLength(); int floatsPerVec; // // For each trim curve, check its linkage to find out if it should be // continued on to the previous trim curve or if it should begin a // new trim curve. Then, send the trim to the NURBS library. // for (i=0; i<numTrims; i++) { GLfloat *dTrimCoords; GLfloat *dtmp; float *ftmp; // Get the trim curve. profile = (SoProfile *)trimNodes[(int) i]; profile->getTrimCurve (action->getState(), numTrimCoords, trimCoords, floatsPerVec, numKnots, trimKnots); // Check for degenerate trim curves if (numTrimCoords == 0) continue; // Check the linkage. if ((profile->linkage.getValue() == SoProfileElement::START_FIRST) || (profile->linkage.getValue() == SoProfileElement::START_NEW)) { if (haveTrim) gluEndTrim(nurbsObj); gluBeginTrim(nurbsObj); haveTrim = TRUE; } // Set the data type of the control points to non-rational or rational if (floatsPerVec == 2) type = (GLenum)GLU_MAP1_TRIM_2; else type = (GLenum)GLU_MAP1_TRIM_3; offset = floatsPerVec; dTrimCoords = new GLfloat[numTrimCoords*floatsPerVec]; dtmp = dTrimCoords; ftmp = trimCoords; for (j=0; j<floatsPerVec*numTrimCoords; j++) *dtmp++ = (GLfloat)(*ftmp++); if (numKnots == 0) { // Send down a Piecewise Linear Trim Curve gluPwlCurve (nurbsObj, (GLint)numTrimCoords, dTrimCoords, (GLint)offset, type); } else { // Send down a NURBS Trim Curve GLfloat *dTrimKnots = new GLfloat[numKnots]; dtmp = dTrimKnots; ftmp = trimKnots; for (j=0; j<numKnots; j++) *dtmp++ = (GLfloat)(*ftmp++); gluNurbsCurve (nurbsObj, (GLint)numKnots, dTrimKnots, (GLint)offset, dTrimCoords, (GLint)(numKnots - numTrimCoords), type); delete[] dTrimKnots; delete[] trimKnots; } delete[] dTrimCoords; delete[] trimCoords; } if (haveTrim) gluEndTrim(nurbsObj); gluEndSurface(nurbsObj); gluDeleteNurbsRenderer(nurbsObj); glDisable(GL_AUTO_NORMAL); delete[] dvKnots; delete[] duKnots; delete[] dCoords; }
/*************************************************************************** DrawTrace ****************************************************************************/ static void DrawTrace(int snum){ int i = 0; float comx = 0.0, comy = 0.0, comz = 0.0; struct coord *c = state->coords[snum]; for (i=0; i<c->size; i++){ comx += c->rp_ca[i].x; comy += c->rp_ca[i].y; comz += c->rp_ca[i].z; } comx /= c->size; comy /= c->size; comz /= c->size; GLUnurbsObj *nurbs = gluNewNurbsRenderer(); GLfloat* ctrlpts = E_MALLOC(12*sizeof(GLfloat)*c->size); for(i=0; i < c->size*12; i+=12){ ctrlpts[i] = c->rp_n[i/12].x - comx; ctrlpts[i+1] = c->rp_n[i/12].y - comy; ctrlpts[i+2] = c->rp_n[i/12].z - comz; ctrlpts[i+3] = 1.0; ctrlpts[i+4] = c->rp_ca[i/12].x - comx; ctrlpts[i+5] = c->rp_ca[i/12].y - comy; ctrlpts[i+6] = c->rp_ca[i/12].z - comz; ctrlpts[i+7] = 1.0; ctrlpts[i+8] = c->rp_c[i/12].x - comx; ctrlpts[i+9] = c->rp_c[i/12].y - comy; ctrlpts[i+10] = c->rp_c[i/12].z - comz; ctrlpts[i+11] = 1.0; } GLfloat* knots = E_MALLOC(sizeof(GLfloat)*(c->size*3+4)); for(i=0; i < c->size*3+4; i++){ if(i>c->size*3+2){ knots[i]=knots[c->size*3+2]; } else{ knots[i]=i/1.0-i%1; } } glColor3f(0.0, 0.0, 1.0); if(snum%3 == 1){ glColor3f(1.0, 0.0, 0.0); } else if(snum%3 == 2){ glColor3f(0.0, 1.0, 0.0); } else{ glColor3f(0.0, 1.0, 0.0); } glLineWidth(2); glPushMatrix(); gluNurbsCallback(nurbs, GLU_ERROR, (GLvoid(*)())nurbsError); gluBeginCurve(nurbs); gluNurbsCurve(nurbs, //context object c->size*3+4, //number of knots knots, //knot pointer 4, //width of control points ctrlpts, //control point pointer 4, //order of the curve (degree+1) GL_MAP1_VERTEX_4 //type ); gluEndCurve(nurbs); glPopMatrix(); }
void drawBranchObject(node a, BranchAttributeObj branchAttributes, float radius1,float radius2) // Draw a cylinder subtending a node, using precomputed values from trig routine // This is currently the only place in the code I need GL_LIGHTING on // This is drawn in the original object coordinate system in which the tree is centered on 0,0 // TO DO enable attenuate on/off flag // Not doing blending or lod_cutoff for tubes yet // Currently doing the lod_cutoff for branchStyle==line only ; makes a big difference { extern GLUquadricObj *qobj; GLfloat params[4]; GLboolean valid; float darkness; float xdist,ydist,zdist; float sknots[8] = { 0,0,0,0,1,1,1,1}; GLfloat ctlpoints[4][4]; // four control points = 2 end points + two "control" points area A,Aanc; double dx,dy,dz,zr,xcross,ycross,theta, color, color_anc; A=(area)(a->data); float r1,r2,z1,z2; if (branchAttributes->branchCurvy == nurbs) // set up control points { // TO DO. CURRENTLY THESE CONTROL POINTS ARE ALL IN A VERTICAL PLANE. MAKE THE TREE CURVIER YET BY MOVING THEM OFF THIS PLANE. // Setting up the two endpoints of the edge; cubic spline will interpolate these two points // NB. These are bogus for circle layout, because there is no variation in the z-axis there, ctlpoints[0][0]=A->x_anc; ctlpoints[0][1]=A->y_anc; ctlpoints[0][2]=A->z_anc; ctlpoints[0][3]=1.0; ctlpoints[3][0]=A->x_center; ctlpoints[3][1]=A->y_center; ctlpoints[3][2]=A->z; ctlpoints[3][3]=1.0; // Setting up the two control points. These are each tweaked with a z parameter and an r parameter in the vertical plane // defined by the two endpoints of the edge, such that both when (r,z) is (0,0) at anc node and (1,1) at desc node. // So we need an (r,z) for each control point: r1,z1,r2,z2. xdist = A->x_center - A->x_anc; ydist = A->y_center - A->y_anc; zdist = A->z - A->z_anc; extern float gr1,gr2,gz1,gz2; r1 = gr1; //branchAttributes->ctlpointParms[0]; z1 = gz1; //branchAttributes->ctlpointParms[1]; r2 = gr2; //branchAttributes->ctlpointParms[2]; z2 = gz2; //branchAttributes->ctlpointParms[3]; ctlpoints[1][0]=A->x_anc + xdist*r1; ctlpoints[1][1]=A->y_anc + ydist*r1; ctlpoints[1][2]=A->z_anc + zdist*z1; ctlpoints[1][3]=1.0; ctlpoints[2][0]=A->x_anc + xdist*r2; ctlpoints[2][1]=A->y_anc + ydist*r2; ctlpoints[2][2]=A->z_anc + zdist*z2; ctlpoints[2][3]=1.0; } switch (branchAttributes->branchStyle) { case tube: { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); switch (branchAttributes->branchCurvy) { case nurbs: { if (a->marked) { darkness=1; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); } else darkness = setColorWithAttenuationLineSegment(A->x_center,A->y_center,A->z, A->x_anc,A->y_anc,A->z_anc, &(branchAttributes->color[0]), branchAttributes->attenuateFactor); // Turn off actual rendering here...no need to draw the line, just get callbacks...use GLU_tesselator gluNurbsProperty(theNurbs,GLU_NURBS_MODE,GLU_NURBS_TESSELLATOR); gluBeginCurve(theNurbs); gluNurbsCurve(theNurbs, 8, sknots, 4, &ctlpoints[0][0], 4, GL_MAP1_VERTEX_4); gluEndCurve(theNurbs); gluNurbsProperty(theNurbs,GLU_NURBS_MODE,GLU_NURBS_RENDERER); int i; float gleColor[500][4]; double gleRadius[500]; for (i=0; i<gNpoints; i++) // set the vectors of colors and radii { if (gNpoints > 500) exit(1); gleColor[i][0]= branchAttributes->color[0]; gleColor[i][1]= branchAttributes->color[1]; gleColor[i][2]= branchAttributes->color[2]; gleColor[i][3]= darkness; // don't seem to need this shit; taken care of by glMaterial if (gNpoints > 1) gleRadius[i] = radius1 + (radius2-radius1)*i/(gNpoints-1); // interpolate to vary radius between nodes of branch else gleRadius[i] = radius1; } params[0]=branchAttributes->color[0]; params[1]=branchAttributes->color[1]; params[2]=branchAttributes->color[2]; params[3]=darkness; params[3]=1.0; //override for now; I don't like how the blending looks glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //glEnable(GL_LINE_SMOOTH); //glHint(GL_LINE_SMOOTH_HINT,GL_NICEST); // Antialiasing not working in this gle environment //glEnable(GL_POLYGON_SMOOTH); //glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, params); gleSetJoinStyle(TUBE_JN_ROUND) ; //glePolyCylinder(gNpoints,gPoint_array,gleColor,radius2); //glePolyCone_c4f(gNpoints,gPoint_array,gleColor,gleRadius); // Note if we pass gleColor, that overrides the material color and its alpha blending; // so to enable blending pass NULL in place of gleColor, and set glMaterial above glePolyCone_c4f(gNpoints,gPoint_array,NULL,gleRadius); //drawCylinder(gPoint_array[0][0],gPoint_array[0][1],gPoint_array[0][2], gPoint_array[1][0],gPoint_array[1][1],gPoint_array[1][2],radius1, radius1); // add gumby cyls at ends of gle cylinder //drawCylinder(gPoint_array[gNpoints-2][0],gPoint_array[gNpoints-2][1],gPoint_array[gNpoints-2][2], gPoint_array[gNpoints-1][0],gPoint_array[gNpoints-1][1],gPoint_array[gNpoints-1][2],radius2, radius2); // Because gle does not extrude at the two endpoints, I draw cylinders at each endpoint. To avoid gappiness at borders, I overlap the cylinder with the extruded tube by one segment (one point on the polyline), thus I run the cylinder from, e.g., point 0 to point 2, where the extrusion starts at 1. drawCylinder(gPoint_array[0][0],gPoint_array[0][1],gPoint_array[0][2], gPoint_array[2][0],gPoint_array[2][1],gPoint_array[2][2],gleRadius[0], gleRadius[2]); // add gumby cyls at ends of gle cylinder drawCylinder(gPoint_array[gNpoints-3][0],gPoint_array[gNpoints-3][1],gPoint_array[gNpoints-3][2], gPoint_array[gNpoints-1][0],gPoint_array[gNpoints-1][1],gPoint_array[gNpoints-1][2],gleRadius[gNpoints-3],gleRadius[gNpoints-1]); //glDisable(GL_LIGHTING); break; } case straight: { params[0]=branchAttributes->color[0]; params[1]=branchAttributes->color[1]; params[2]=branchAttributes->color[2]; params[3]=darkness; glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, params); drawCylinder(A->x_anc,A->y_anc,A->z_anc, A->x_center,A->y_center,A->z, radius1, radius2); break; } } glDisable(GL_LIGHTING); break; } case line: { if (!isRoot(a)) { glLineWidth(branchAttributes->lineWidth); if (a->marked) { darkness=1; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glColor4f(branchAttributes->color[0],branchAttributes->color[1],branchAttributes->color[2],darkness); } else darkness = setColorWithAttenuationLineSegment(A->x_center,A->y_center,A->z, A->x_anc,A->y_anc,A->z_anc, &(branchAttributes->color[0]), branchAttributes->attenuateFactor); // there is similar code in function setColorWithAttenuation() in tree_openGL, but here we have something more elaborate... switch (branchAttributes->branchCurvy) { case nurbs: { if (branchAttributes->lod_cutoff < darkness) { gluNurbsProperty(theNurbs,GLU_NURBS_MODE,GLU_NURBS_RENDERER); gluBeginCurve(theNurbs); gluNurbsCurve(theNurbs, 8, sknots, 4, &ctlpoints[0][0], 4, GL_MAP1_VERTEX_4); gluEndCurve(theNurbs); } break; } case straight: { if (branchAttributes->lod_cutoff < darkness) { glBegin(GL_LINES); glVertex3d(A->x_anc,A->y_anc,A->z_anc); glVertex3d(A->x_center,A->y_center,A->z); glEnd(); } } } break; } } } }
void CMeter2DGraphView::DrawValueGraph() { TRACE_FUN( Frequently, "CMeter2DGraphView::DrawValueGraph" ); float meshWidth( model()->timeFrame() ); float meshHeight( model()->valueFrame() ); glViewport( _meshArea.x(), _meshArea.y(), _meshArea.width(), _meshArea.height() ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluOrtho2D( 0, meshWidth, 0, meshHeight ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glEnable( GL_LINE_SMOOTH ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glColor4f( .0, .0, .0, .7 ); glLineWidth( width() / 400 ); const CMeter2DGraphModel::TValueTimeContainer& valueTimeContainer( model()->valueTimeContainer() ); int knotCount( valueTimeContainer.size() * 4 + 4 ); int pointCount( valueTimeContainer.size() * 4 * 3 ); float* knots( new float[ knotCount ] ); float* cpoints( new float[ pointCount + 12 ] ); int knot( 0 ); int timeOffset( int( rint( model()->timeOffset() ) ) ); for( CMeter2DGraphModel::TValueTimeContainer::const_iterator I_value( valueTimeContainer.begin() ); I_value != valueTimeContainer.end(); ) { knots[ knot * 4 + 0 ] = knot; knots[ knot * 4 + 1 ] = knot; knots[ knot * 4 + 2 ] = knot; knots[ knot * 4 + 3 ] = knot; float xPoint( ( int( I_value->second ) + timeOffset ) / 1000. ); cpoints[ knot * 4 * 3 + 0 ] = xPoint; cpoints[ knot * 4 * 3 + 1 ] = I_value->first; cpoints[ knot * 4 * 3 + 2 ] = 0; cpoints[ knot * 4 * 3 + 3 ] = xPoint; cpoints[ knot * 4 * 3 + 4 ] = I_value->first; cpoints[ knot * 4 * 3 + 5 ] = 0; cpoints[ knot * 4 * 3 + 6 ] = xPoint; cpoints[ knot * 4 * 3 + 7 ] = I_value->first; cpoints[ knot * 4 * 3 + 8 ] = 0; cpoints[ knot * 4 * 3 + 9 ] = xPoint; cpoints[ knot * 4 * 3 + 10 ] = I_value->first; cpoints[ knot * 4 * 3 + 11 ] = 0; ++I_value; if( I_value != valueTimeContainer.end() ) { float xPoint( ( int( I_value->second ) + timeOffset ) / 1000. ); cpoints[ knot * 4 * 3 + 6 ] = cpoints[ knot * 4 * 3 + 3 ]; cpoints[ knot * 4 * 3 + 3 ] = xPoint; cpoints[ knot * 4 * 3 + 7 ] = cpoints[ knot * 4 * 3 + 4 ]; cpoints[ knot * 4 * 3 + 4 ] = I_value->first; cpoints[ knot * 4 * 3 + 8 ] = 0; /////////////////////////////////////////////////////////////////////////////////// float xcorr( ( cpoints[ knot * 4 * 3 + 3 ] - cpoints[ knot * 4 * 3 + 6 ] ) * .6 ); cpoints[ knot * 4 * 3 + 3 ] -= xcorr; cpoints[ knot * 4 * 3 + 6 ] += xcorr; float ycorr( ( cpoints[ knot * 4 * 3 + 4 ] - cpoints[ knot * 4 * 3 + 7 ] ) * 1. ); cpoints[ knot * 4 * 3 + 4 ] -= ycorr; cpoints[ knot * 4 * 3 + 7 ] += ycorr; /////////////////////////////////////////////////////////////////////////////////// cpoints[ knot * 4 * 3 + 9 ] = xPoint; cpoints[ knot * 4 * 3 + 10 ] = I_value->first; cpoints[ knot * 4 * 3 + 11 ] = 0; } ++knot; } knots[ knot * 4 + 0 ] = knot; knots[ knot * 4 + 1 ] = knot; knots[ knot * 4 + 2 ] = knot; knots[ knot * 4 + 3 ] = knot; gluBeginCurve( _nurbsRenderer ); gluNurbsCurve( _nurbsRenderer, knotCount, knots, 3, cpoints, 4, GL_MAP1_VERTEX_3 ); gluEndCurve( _nurbsRenderer ); delete[] cpoints; delete[] knots; }