/* nurb:EndSurface() -> nurb */ static int luaglu_end_surface(lua_State *L) { LuaGLUnurb *lnurb=luaglu_checknurb(L,1); gluEndSurface(lnurb->nurb); lua_pushvalue(L,1); return 1; }
void drawGrass() { int i, j, k; int num = 0; glPushMatrix(); glTranslatef(0.0, -5.0, 0.0); glColor3f(0.0, grasscolor, 0.0); for (i = -GRASSAREA; i<GRASSAREA; ++i){ for (j = -GRASSAREA; j<GRASSAREA; ++j){ glPushMatrix(); glTranslatef((0.5 + i + ((randx[num] % (100 + 1)) / 100.0 - 0.5)) / 4.0, 0.0, (0.5 + j + ((randz[num] % (100 + 1)) / 100.0 - 0.5)) / 4.0); glRotatef(90 * (randrotation[num] % 101) / 100, 0.0, 1.0, 0.0); for (k = 0; k<4; ++k) { cpoint[3][k][2] = 0.2*sin(2 * PI*(randrotation[num] % 100 + 1) / 100 + thetagrass*PI / 180.0)*(1 - wind) + (0.5*sin(90 * (randrotation[num] % 101) / 100 * PI / 180.0))*wind; cpoint[3][k][0] = 0.5*cos(90 * (randrotation[num] % 101) / 100 * PI / 180.0)*wind; cpoint[3][k][1] = 0.5 + 0.05*sin(2 * PI*(randrotation[num] % 100 + 1) / 100 + thetawind*PI / 180.0)*wind; } gluBeginSurface(nrb_obj); gluNurbsSurface(nrb_obj, 8, knotvec_u, 8, knotvec_v, 3, 3 * 4, &cpoint[0][0][0], 4, 4, GL_MAP2_VERTEX_3 ); gluEndSurface(nrb_obj); glPopMatrix(); ++num; } } glPopMatrix(); }
void display(void) { GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; int i, j; 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); gluEndSurface(theNurb); if (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(ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]); } } glEnd(); glEnable(GL_LIGHTING); } glPopMatrix(); glFlush(); }
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 INuPatchDrw::draw( const DrawContext &iCtx ) { const V3f * points = m_positions -> get(); const float *u_knot = m_uKnot -> get(); const float *v_knot = m_vKnot -> get(); size_t nknotu = m_uKnot -> size(); size_t nknotv = m_vKnot -> size(); glColor3f(1.0, 1.0, 1.0); gluBeginSurface(nurb); gluNurbsSurface( nurb, nknotu, (GLfloat *) &u_knot[0], nknotv, (GLfloat *) &v_knot[0], 3, m_nu*3, // stride (GLfloat *)&points[0][0], m_uOrder, m_vOrder, //orders GL_MAP2_VERTEX_3 ); gluEndSurface(nurb); IObjectDrw::draw( iCtx ); }
static void Draw(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(4.0, 4.5, 2.5); glRotatef(rotY, 1, 0, 0); glRotatef(rotX, 0, 1, 0); glTranslatef(-4.0, -4.5, -2.5); gluBeginSurface(theNurbs); gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots, 4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER, T_ORDER, GL_MAP2_VERTEX_4); gluEndSurface(theNurbs); glPopMatrix(); glFlush(); if (doubleBuffer) { glutSwapBuffers(); } }
void myDisplayObject( const ON_Object& geometry, const ON_Material& material, GLUnurbsObj* nobj ) { // Called from myDisplay() to show geometry. // Uses ON_GL() functions found in rhinoio_gl.cpp. const ON_Point* point=0; const ON_PointCloud* cloud=0; const ON_Brep* brep=0; const ON_Mesh* mesh=0; const ON_Curve* curve=0; const ON_Surface* surface=0; // specify rendering material ON_GL( material ); brep = ON_Brep::Cast(&geometry); if ( brep ) { ON_GL(*brep, nobj); return; } mesh = ON_Mesh::Cast(&geometry); if ( mesh ) { ON_GL(*mesh); return; } curve = ON_Curve::Cast(&geometry); if ( curve ) { ON_GL( *curve, nobj ); return; } surface = ON_Surface::Cast(&geometry); if ( surface ) { gluBeginSurface( nobj ); ON_GL( *surface, nobj ); gluEndSurface( nobj ); return; } point = ON_Point::Cast(&geometry); if ( point ) { ON_GL(*point); return; } cloud = ON_PointCloud::Cast(&geometry); if ( cloud ) { ON_GL(*cloud); return; } }
void display(void) { GLfloat knots1[12] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 , 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; GLfloat knots2[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; int i, j; GLfloat edgePt[5][2] = {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}}; GLfloat pwlPt[42][2]; for(unsigned int k = 0; k < 42; ++k) { pwlPt[k][0] = 0.5 + 0.3 * cos(2.0*PI*k/41.0); pwlPt[k][1] = 0.5 + 0.3 * sin(-2.0*PI*k/41.0); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(330.0, 1.,0.,0.); glScalef (0.3, 0.3, 0.3); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, 12, knots1, 8, knots2, 4 * 3, 3, &ctlpoints[0][0][0], 6, 4, GL_MAP2_VERTEX_3); // trim gluBeginTrim (theNurb); gluPwlCurve(theNurb, 5, &edgePt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (theNurb); gluBeginTrim (theNurb); gluPwlCurve (theNurb, 42, &pwlPt[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (theNurb); gluEndSurface(theNurb); if (showPoints) { glPointSize(5.0); glDisable(GL_LIGHTING); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 8; i++) { for (j = 0; j < 4; j++) { glVertex3f(ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]); } } glEnd(); glEnable(GL_LIGHTING); } glPopMatrix(); glFlush(); }
void GraphicsPainter::drawNurbsSurface(const QVector<Point3f> &controlPoints, const QVector<float> &uKnots, const QVector<float> &vKnots, int uOrder, int vOrder) { // nurbs control points QVector<float> points(controlPoints.size() * 3); for(int i = 0; i < controlPoints.size(); i++){ points[i*3+0] = controlPoints[i].x(); points[i*3+1] = controlPoints[i].y(); points[i*3+2] = controlPoints[i].z(); } // nurbs knot vectors QVector<float> uKnotVector(uKnots.size()); for(int i = 0; i < uKnots.size(); i++) uKnotVector[i] = uKnots[i]; QVector<float> vKnotVector(vKnots.size()); for(int i = 0; i < vKnots.size(); i++) vKnotVector[i] = vKnots[i]; int uStride = 3 * (vKnotVector.size() - vOrder); int vStride = 3; glEnable(GL_AUTO_NORMAL); GLUnurbsObj *nurb = gluNewNurbsRenderer(); gluNurbsProperty(nurb, GLU_CULLING, GL_TRUE); // only render visible parts of the surface gluNurbsProperty(nurb, GLU_V_STEP, 4); gluNurbsProperty(nurb, GLU_U_STEP, 10); gluNurbsProperty(nurb, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE); #ifdef Q_OS_WIN gluNurbsCallback(nurb, GLU_ERROR, (void (__stdcall *)()) nurbsErrorCallback); #else gluNurbsCallback(nurb, GLU_ERROR, (void (*)()) nurbsErrorCallback); #endif gluBeginSurface(nurb); gluNurbsSurface(nurb, uKnotVector.size(), uKnotVector.data(), vKnotVector.size(), vKnotVector.data(), uStride, vStride, points.data(), uOrder, vOrder, GL_MAP2_VERTEX_3); gluEndSurface(nurb); gluDeleteNurbsRenderer(nurb); glDisable(GL_AUTO_NORMAL); }
// 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 gluBeginSurface(pNurb); // Evaluate the surface gluNurbsSurface(pNurb, // pointer to NURBS renderer 8, Knots, // No. of knots and knot array u direction 8, Knots, // No. of knots and knot array v direction 4 * 3, // Distance between control points in u dir. 3, // Distance between control points in v dir. &ctrlPoints[0][0][0], // Control points 4, 4, // u and v order of surface GL_MAP2_VERTEX_3); // Type of surface // Outer area, include entire curve gluBeginTrim (pNurb); gluPwlCurve (pNurb, 5, &outsidePts[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (pNurb); // Inner triangluar area gluBeginTrim (pNurb); gluPwlCurve (pNurb, 4, &insidePts[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim (pNurb); // Done with surface gluEndSurface(pNurb); // Restore the modelview matrix glPopMatrix(); // Dispalay the image glutSwapBuffers(); }
/* drawing ghost with NURBS spline */ void DrawGhost(void) { // control points for bezier curve GLfloat ctlpoints[4][4][3] = { { {-3., -5., 0.}, {-5., -2., -5.}, {-5., 2., -5.}, {-3., 3., 0.} }, { {-2., -3., 0.}, {-2., -2., 5.}, {-2., 2., 5.}, {-2., 5., 0.} }, { {2., -3., 0.}, {2., -2., -5.}, {2., 2., -5.}, {2., 5., 0.} }, { {3., -5., 0.}, {5., -2., 5.}, {5., 2., 5.}, {3., 3., 0.} } }; GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; gluBeginSurface(theGhostNurb); gluNurbsSurface(theGhostNurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3); // map the vertices gluNurbsSurface(theGhostNurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_NORMAL); // map the normals gluEndSurface(theGhostNurb); // draw eyes with two white spheres glPushMatrix(); glColor3f(1.0f, 1.0f, 1.0f); glTranslatef(1.5, 1.5, 0.); glutSolidSphere(0.5, 5, 5); glTranslatef(-3., 0., 0.); glutSolidSphere(0.5, 5, 5); glPopMatrix(); /* for testing the points of bezier curve glPointSize(5.0); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { glVertex3f(ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]); printf("point: %lf %lf %lf", ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]); } } glEnd(); */ }
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 RenderScene(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); //修剪框是一个闭合的环 //外修剪框 GLfloat outSidePts[5][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}}; //内修剪框 GLfloat inSidePts[4][2] = {{0.25f, 0.25f}, { 0.5f, 0.5f}, {0.75f, 0.25f},{0.25f, 0.25f} }; gluBeginSurface(pNurb); //定义NURBS表面 gluNurbsSurface(pNurb, 8, Knots, //u定义域内的结点个数,以及结点序列 8, Knots,//v定义域内的结点个数,以及结点序列 4 * 3, //u方向上的控制点间隔 3, //v方向上的控制点间隔 &ctrlPoints[0][0][0], //控制点数组 4, 4, //u v的次数 GL_MAP2_VERTEX_3);//产生的类型 //开始修剪 gluBeginTrim(pNurb); gluPwlCurve(pNurb, 5, //修剪点的个数 &outSidePts[0][0], //修剪点数组 2, //点之间的间隔 GLU_MAP1_TRIM_2);//修剪的类型 gluEndTrim(pNurb); gluBeginTrim(pNurb); gluPwlCurve(pNurb, 4, &inSidePts[0][0], 2, GLU_MAP1_TRIM_2); gluEndTrim(pNurb); gluEndSurface(pNurb); DrawPoints(); glPopMatrix(); glutSwapBuffers(); }
void draw_solid(const k3d::gl::render_state& State, const k3d::double_t Height, const k3d::double_t Radius, const k3d::double_t SweepAngle) { if(!Radius) return; k3d::mesh::knots_t knots; k3d::mesh::weights_t weights; k3d::mesh::points_t arc_points; k3d::nurbs_curve::circular_arc(k3d::vector3(1, 0, 0), k3d::vector3(0, 1, 0), 0, SweepAngle, 4, knots, weights, arc_points); std::vector<GLfloat> gl_u_knot_vector(knots.begin(), knots.end()); std::vector<GLfloat> gl_v_knot_vector; std::vector<GLfloat> gl_control_points; gl_v_knot_vector.insert(gl_v_knot_vector.end(), 2, 0); gl_v_knot_vector.insert(gl_v_knot_vector.end(), 1); gl_v_knot_vector.insert(gl_v_knot_vector.end(), 2, 2); const k3d::point3 offset = Height * k3d::point3(0, 0, 1); for(k3d::uint_t i = 0; i <= 2; ++i) { const k3d::double_t radius2 = k3d::mix(Radius, 0.001 * Radius, static_cast<k3d::double_t>(i) / static_cast<k3d::double_t>(2)); for(k3d::uint_t j = 0; j != arc_points.size(); ++j) { gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][0] + offset[0])); gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][1] + offset[1])); gl_control_points.push_back(weights[j] * (radius2 * arc_points[j][2] + offset[2])); gl_control_points.push_back(weights[j]); } } GLUnurbsObj* const nurbs_renderer = gluNewNurbsRenderer(); // Important! We load our own matrices for efficiency (saves round-trips to the server) and to prevent problems with selection gluNurbsProperty(nurbs_renderer, GLU_AUTO_LOAD_MATRIX, GL_FALSE); gluNurbsProperty(nurbs_renderer, GLU_CULLING, GL_TRUE); GLfloat gl_modelview_matrix[16]; glGetFloatv(GL_MODELVIEW_MATRIX, gl_modelview_matrix); gluLoadSamplingMatrices(nurbs_renderer, gl_modelview_matrix, State.gl_projection_matrix, State.gl_viewport); gluBeginSurface(nurbs_renderer); gluNurbsSurface(nurbs_renderer, gl_u_knot_vector.size(), &gl_u_knot_vector[0], gl_v_knot_vector.size(), &gl_v_knot_vector[0], 4, 36, &gl_control_points[0], 3, 2, GL_MAP2_VERTEX_4); gluEndSurface(nurbs_renderer); gluDeleteNurbsRenderer(nurbs_renderer); }
static void Init(void) { theNurbs = gluNewNurbsRenderer(); gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback); gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0); gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH); expectedError = GLU_INVALID_ENUM; gluNurbsProperty(theNurbs, ~0, 15.0); expectedError = GLU_NURBS_ERROR13; gluEndSurface(theNurbs); expectedError = 0; glColor3f(1.0, 1.0, 1.0); }
void nurbsInit(void) { theNurbs = gluNewNurbsRenderer(); gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback); gluNurbsProperty(theNurbs,GLU_NURBS_MODE,GLU_NURBS_TESSELLATOR); gluNurbsCallback(theNurbs,GLU_NURBS_BEGIN,beginCallback); gluNurbsCallback(theNurbs,GLU_NURBS_END,endCallback); gluNurbsCallback(theNurbs,GLU_NURBS_VERTEX,vertexCallback); gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0); gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH); expectedError = GLU_INVALID_ENUM; gluNurbsProperty(theNurbs, ~0, 15.0); expectedError = GLU_NURBS_ERROR13; gluEndSurface(theNurbs); expectedError = 0; }
void draw_local() { int i,j; GLfloat knots[8] = {0,1,2,3,4,5,6,7}; GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 100.0 }; glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL); gluNurbsCallback(theNurb, GLU_ERROR, (GLvoid (*)()) nurbsError); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, 8, knots, 8, knots, 3*6, 3, &ctlpoints[0][0][0], 2, 2, GL_MAP2_VERTEX_3); gluEndSurface(theNurb); if (showPoints) { glPointSize(5.0); glDisable(GL_LIGHTING); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i=0; i<6; i++) { for (j=0; j<6; j++) { glVertex3f(ctlpoints[i][j][0], ctlpoints[i][j][1], ctlpoints[i][j][2]); } } glEnd(); glEnable(GL_LIGHTING); } gluDeleteNurbsRenderer(theNurb); }
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(); }
/* Draw the nurb, possibly with trimming */ void draw_nurb(GLboolean trimming) { static GLfloat angle = 0.0; int i,j; /* wave the flag by rotating Z coords though a sine wave */ for (i=1; i<4; i++) for (j=0; j<4; j++) ctlpoints[i][j][2] = sin((GLfloat)i+angle); angle += 0.1; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(2.5,-1.0,0.0); glScalef(1.5,1.0,1.0); glRotatef(90,0.,0.,1.); glRotatef(mousey/10.,1.,0.,0.); glRotatef(mousex/10.,0.,1.,0.); gluBeginSurface(nurbsflag); gluNurbsSurface(nurbsflag,S_NUMKNOTS, sknots, T_NUMKNOTS, tknots, 3 * T_NUMPOINTS, 3, &ctlpoints[0][0][0], T_ORDER, S_ORDER, GL_MAP2_VERTEX_3); if (trimming) { dotrim(whole); dotrim(path[0]); dotrim(path[1]); dotrim(path[2]); } gluEndSurface(nurbsflag); if (hull) draw_hull(ctlpoints); glPopMatrix(); }
static int tolua_glu_gluEndSurface00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"GLUnurbsObj",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { GLUnurbsObj* nobj = ((GLUnurbsObj*) tolua_tousertype(tolua_S,1,0)); { gluEndSurface(nobj); } } return 0; #ifndef TOLUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'gluEndSurface'.",&tolua_err); return 0; #endif }
/*************************************************** * 用NURBS工具渲染水波纹 **************************************************/ void drawWave(void) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glMaterialfv(GL_FRONT, GL_DIFFUSE, wave_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, wave_specular); glMaterialfv(GL_FRONT, GL_SHININESS, wave_shininess); gluBeginSurface(waveSur); if (du % 2 == 0) { gluNurbsSurface(waveSur, ORDER * 4, knots, ORDER * 4, knots, ORDER * 2 * 3, 3, &ctlPoints[0][0][0], ORDER * 2, ORDER * 2, GL_MAP2_VERTEX_3); } else { gluNurbsSurface(waveSur, ORDER * 4, knots, ORDER * 4, knots, ORDER * 2 * 3, 3, &ctlPoints1[0][0][0], ORDER * 2, ORDER * 2, GL_MAP2_VERTEX_3); } gluEndSurface(waveSur); glPopMatrix(); }
/* drawing fruit with NURBS spline */ void DrawFruit(void) { // control points for bezier curve GLfloat fruit_ctlpoints[4][4][3] = { { {-3., -2., 0.}, {-5., -1., -3.}, {-5., 2., -3.}, {-3., 5., -3.} }, { {-1., -4., 0.}, {-2., -2., 3.}, {-2., 1., 3.}, {-1., 2., -3.} }, { {1., -4., 0.}, {2., -3., 3.}, {2., -2., 3.}, {1., -1., -3.} }, { {3., -2., 0.}, {5., 0., -3.}, {5., -1., -3.}, {3., 1., -3.} } }; GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; gluBeginSurface(theFruitNurb); // map the vertices gluNurbsSurface(theFruitNurb, 8, knots, 8, knots, 4 * 3, 3, &fruit_ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3); // map the normals gluNurbsSurface(theFruitNurb, 8, knots, 8, knots, 4 * 3, 3, &fruit_ctlpoints[0][0][0], 4, 4, GL_MAP2_NORMAL); gluEndSurface(theFruitNurb); }
static void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef (4., 4.5, 2.5); glRotatef (220.0, 1., 0., 0.); glRotatef (115.0, 0., 1., 0.); glTranslatef (-4., -4.5, -2.5); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots, 4 * T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER, T_ORDER, GL_MAP2_VERTEX_4); gluEndSurface(theNurb); glPopMatrix(); glFlush(); }
void display (void) { glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer glMatrixMode( GL_MODELVIEW ); glColor4f(1.0f,0.0f,0.0f,1.0f); glEnable(GL_SCISSOR_TEST); glMatrixMode (GL_PROJECTION); //set the matrix to projection // Draw the primary view glViewport (0, 0, (GLsizei)screen_width, (GLsizei)screen_height); //set the viewport to the current window specifications glScissor(0, 0, (GLsizei)screen_width, (GLsizei)screen_height); glLoadIdentity (); if (lighting) { GLfloat AmbientLight[] = {0.1, 0.1, 0.2}; glLightfv (GL_LIGHT0, GL_AMBIENT, AmbientLight); GLfloat DiffuseLight[] = {1, 1, 1}; glLightfv (GL_LIGHT1, GL_DIFFUSE, DiffuseLight); GLfloat LightPosition[] = {xpos, ypos, zpos, 1}; glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); } gluPerspective (60, (GLfloat)screen_width / (GLfloat)screen_height, 1.0, 100.0); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //camera position, x,y,z, looking at x,y,z, Up Positions of the camera camera(); glPushMatrix(); if (lighting) { texture1 = LoadTexture( "texture.raw", 256, 256 ); texture2 = LoadTexture( "/dev/urandom", 256, 256 ); texture3 = LoadTexture( "water.raw", 500, 375 ); texture4 = LoadTexture( "bubbles.raw", 200, 200 ); glEnable( GL_TEXTURE_2D ); //enable 2D texturing glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation glEnable(GL_TEXTURE_GEN_T); if (fog) { GLfloat fogColor[4]= {0.5f, 1.0f, 0.5f, 1}; // Fog Color glFogi(GL_FOG_MODE, GL_EXP); // Fog Mode glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color glFogf(GL_FOG_DENSITY, 1.0f); // How Dense Will The Fog Be glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value glFogf(GL_FOG_START, n*space); // Fog Start Depth glFogf(GL_FOG_END,-n*space); // Fog End Depth } if (nurb) { glPushMatrix(); glRotatef(270,0.0,1.0,0.0); glTranslated(n*space/2,n*space/2,-n*space); GLfloat ctlpoints[4][4][3]; GLUnurbsObj *theNurb; GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; int u, v; for (u = 0; u < 4; u++) { for (v = 0; v < 4; v++) { ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5); ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5); if ( (u == 1 || u == 2) && (v == 1 || v == 2)) ctlpoints[u][v][2] = 3.0; else ctlpoints[u][v][2] = -3.0; } } theNurb = gluNewNurbsRenderer(); gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL); gluBeginSurface(theNurb); gluNurbsSurface(theNurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3); gluEndSurface(theNurb); glPopMatrix(); } } cube(); //call the cube drawing function glPopMatrix(); if (lighting) { FreeTexture( texture1 ); FreeTexture( texture2 ); FreeTexture( texture3 ); FreeTexture( texture4 ); } glPushMatrix(); glTranslated(space*((n/2)+1),space*(n/2),space*(n/2)); glutWireCube(space*n); glPopMatrix(); // Draw the secondary view glViewport (3*(screen_width/4), 3*(screen_height/4), screen_width/4, screen_width/4); //set the viewport to the current window specifications glScissor(3*(screen_width/4), 3*(screen_height/4), screen_width/4, screen_width/4); glLoadIdentity(); glOrtho(-1, 13, -1, 13, -1, 13); glRotatef(90,0.0,1.0,0.0); cube(); glDisable(GL_SCISSOR_TEST); glutSwapBuffers(); //swap the buffers }
void display(void) { int i,j; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(eixox, 1 ,0 ,0); glRotatef(eixoy, 0 ,1 ,0); glRotatef(eixoz, 0 ,0 ,1); glScalef(0.25, 0.25, 0.25); glPushMatrix(); glGetDoublev (GL_MODELVIEW_MATRIX, matrizModelview); glGetDoublev (GL_PROJECTION_MATRIX, matrizProjecao); glGetIntegerv (GL_VIEWPORT, matrizViewport); glPopMatrix(); glDisable(GL_LIGHTING); glPushMatrix(); glTranslatef(-5,-5,-5); glColor3f(1,1,1); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(1,0,0); glEnd(); glRasterPos3f(1.5,0,0); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'x'); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,1,0); glEnd(); glRasterPos3f(0,1.5,0); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'y'); glBegin(GL_LINES); glVertex3f(0,0,0); glVertex3f(0,0,1); glEnd(); glRasterPos3f(0,0,1.5); glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10, 'z'); glPopMatrix(); glEnable(GL_LIGHTING); switch(spline) { case BEZIER: glEnable(GL_AUTO_NORMAL); glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0, 1, 3*nVertices, 4, &vertices[0][0][0]); glMapGrid2f(20, 0, 1.0, 20, 0, 1.0); glEvalMesh2(GL_FILL, 0, 20, 0, 20); glEnd(); break; case NURBS: gluBeginSurface(nc); gluNurbsSurface(nc, nNosx, nosx, nNosy, nosy, 4*3, 3, &vertices[0][0][0], ordemx, ordemy, GL_MAP2_VERTEX_3); gluEndSurface(nc); break; } glPointSize(5.0); glColor3f(1.0, 0.0, 0.0); glDisable(GL_LIGHTING); glBegin(GL_POINTS); for(i=0; i<4; i++) { for(j=0; j<4; j++) { if((vcx==i)&&(vcy==j)) { glColor3f(1.0,1.0,0.0); glVertex3fv(&vertices[i][j][0]); glColor3f(1.0,0.0,0.0); } else { glVertex3fv(&vertices[i][j][0]); } } } glEnable(GL_LIGHTING); glEnd(); glColor3f(1.0, 1.0, 1.0); glPopMatrix(); glFlush(); glutSwapBuffers(); }
void ON_GL( const ON_BrepFace& face, GLUnurbsObj* nobj // created with gluNewNurbsRenderer ) ) { bool bSkipTrims = false; const ON_Mesh* mesh; mesh = face.Mesh(ON::render_mesh); if ( mesh ) { // use saved render mesh ON_GL(*mesh); } else { // use (slow and buggy) glu trimmed NURBS rendering double knot_scale[2][2] = {{0.0,1.0},{0.0,1.0}}; const ON_Brep* brep = face.Brep(); if ( !brep ) return; // untrimmed surface { ON_NurbsSurface tmp_nurbssrf; const ON_Surface* srf = brep->m_S[face.m_si]; const ON_NurbsSurface* nurbs_srf = ON_NurbsSurface::Cast(srf); if ( !nurbs_srf ) { // attempt to get NURBS form of this surface if ( srf->GetNurbForm( tmp_nurbssrf ) ) nurbs_srf = &tmp_nurbssrf; } if ( !nurbs_srf ) return; gluBeginSurface( nobj ); ON_GL( *nurbs_srf, nobj, (nurbs_srf->IsRational()) ? GL_MAP2_VERTEX_4 : GL_MAP2_VERTEX_3, true, knot_scale[0], knot_scale[1] ); } if ( bSkipTrims || brep->FaceIsSurface( face.m_face_index ) ) { gluEndSurface( nobj ); return; // face is trivially trimmed } int fli, li, lti, ti; // any knot scaling applied to the surface must also be applied to // the parameter space trimming geometry double xform[4][4] = {{knot_scale[0][1], 0.0, 0.0, -knot_scale[0][0]*knot_scale[0][1] }, {0.0, knot_scale[1][1], 0.0, -knot_scale[1][0]*knot_scale[1][1] }, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}}; // Add face's 2d trimming loop(s) const int face_loop_count = face.m_li.Count(); for ( fli = 0; fli < face_loop_count; fli++ ) { gluBeginTrim( nobj ); li = face.m_li[fli]; const ON_BrepLoop& loop = brep->m_L[li]; const int loop_trim_count = loop.m_ti.Count(); for ( lti = 0; lti < loop_trim_count; lti++ ) { ti = loop.m_ti[lti]; const ON_BrepTrim& trim = brep->m_T[ti]; ON_GL( trim, nobj, GLU_MAP1_TRIM_2, xform ); } gluEndTrim( nobj ); } gluEndSurface( nobj ); } }
int NurbsSurface (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; GLint uOrder = 4; GLint vOrder = 4; GLenum type = GL_MAP2_VERTEX_3; int nCoords = 3; FloatArray uKnot = NewFloatArray (); FloatArray vKnot = NewFloatArray (); FloatArray cPoint = NewFloatArray (); GLfloat samplingTolerance = 50.0; GLfloat displayMode = GLU_FILL; GLfloat culling = GL_FALSE; int iarg; int dlist = 0; for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-uorder", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No value given for -uorder"); if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK || val < 2 || val > 8) ERRMSG2 ("\nInvalid value for -uorder:", argv [iarg]); uOrder = val; } else if (strncmp (argv [iarg], "-vorder", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No value given for -vorder"); if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK || val < 2 || val > 8) ERRMSG2 ("\nInvalid value for -vorder:", argv [iarg]); vOrder = val; } else if (strncmp (argv [iarg], "-uknots", len) == 0) { if (uKnot->count != 0) ERRMSG ("uknot values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); if (uKnot->count > 0 && uKnot->value [uKnot->count-1] > val) ERRMSG ("uknot values not in non-descending order"); AddFloat (uKnot, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-vknots", len) == 0) { if (vKnot->count != 0) ERRMSG ("vknot values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); if (vKnot->count > 0 && vKnot->value [vKnot->count-1] > val) ERRMSG ("vknot values not in non-descending order"); AddFloat (vKnot, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-controlpoints", len) == 0) { if (cPoint->count != 0) ERRMSG ("controlpoint values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); AddFloat (cPoint, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-type", len) == 0) { iarg++; if (iarg >= argc) ERRMSG ("No -type value given"); if (strcmp (argv [iarg], "map2vertex3") ==0) { type = GL_MAP2_VERTEX_3; nCoords = 3; } else if (strcmp (argv [iarg], "map2vertex4") == 0) { type = GL_MAP2_VERTEX_4; nCoords = 4; } else if (strcmp (argv [iarg], "map2color4") == 0) { type = GL_MAP2_COLOR_4; nCoords = 4; } else if (strcmp (argv [iarg], "map2normal") == 0) { type = GL_MAP2_NORMAL; nCoords = 3; } else if (strcmp (argv [iarg], "map2texturecoord1") == 0) { type = GL_MAP2_TEXTURE_COORD_1; nCoords = 1; } else if (strcmp (argv [iarg], "map2texturecoord2") == 0) { type = GL_MAP2_TEXTURE_COORD_2; nCoords = 2; } else if (strcmp (argv [iarg], "map2texturecoord3") == 0) { type = GL_MAP2_TEXTURE_COORD_3; nCoords = 3; } else if (strcmp (argv [iarg], "map2texturecoord4") == 0) { type = GL_MAP2_TEXTURE_COORD_4; nCoords = 4; } else ERRMSG2 ("not a valid type:", argv [iarg]); } else if (strncmp (argv [iarg], "-samplingtolerance", len) == 0) { double val; iarg++; if (iarg >= argc) ERRMSG ("No -samplingtolerance value given"); if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing sampling tolerance"); samplingTolerance = (GLfloat)val; } else if (strncmp (argv [iarg], "-displaymode", len) == 0) { iarg++; if (iarg >= argc) ERRMSG ("No -displaymode value given"); if (strcmp (argv [iarg], "fill") == 0) { displayMode = GLU_FILL; } else if (strcmp (argv [iarg], "outlinepolygon") == 0) { displayMode = GLU_OUTLINE_POLYGON; } else if (strcmp (argv [iarg], "outlinepatch") == 0) { displayMode = GLU_OUTLINE_PATCH; } else { ERRMSG2 ("not a valid display mode:", argv [iarg]); } } else if (strncmp (argv [iarg], "-culling", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No -culling value given"); if (Tcl_GetBoolean (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing culling value"); culling = (GLfloat)val; } else { ERRMSG2 ("invalid option:", argv [iarg]); } } if (vKnot->count == 0 || uKnot->count == 0 || cPoint->count == 0) ERRMSG ("All of -uknot, -vknot and -cpoint options must be specified"); /* Now try to guess the remaining arguments and call gluNurbsSurface */ { GLint uKnotCount = uKnot->count; GLint vKnotCount = vKnot->count; GLint vStride = nCoords; GLint uStride = nCoords * (vKnotCount - vOrder); static GLUnurbsObj* obj = NULL; if (uStride * (uKnotCount - uOrder) != cPoint->count) { char buf [80]; sprintf (buf, "%d", uStride * (uKnotCount - uOrder)); ERRMSG2 ("Incorrect number of controlpoint coordinates. Expected ", buf); } /* Theoretically, a nurbs object could be allocated for each invocation of NurbsSurface and then freed after the creation of the display list. However, this produces a segmentation violation on AIX OpenGL 1.0. Thus, only one nurbs object is ever allocated and never freed. */ if (obj == NULL) obj = gluNewNurbsRenderer(); dlist = glGenLists (1); gluNurbsProperty (obj, GLU_SAMPLING_TOLERANCE, samplingTolerance); gluNurbsProperty (obj, GLU_DISPLAY_MODE, displayMode); gluNurbsProperty (obj, GLU_CULLING, culling); glNewList (dlist, GL_COMPILE); gluBeginSurface (obj); gluNurbsSurface (obj, uKnotCount, uKnot->value, vKnotCount, vKnot->value, uStride, vStride, cPoint->value, uOrder, vOrder, type); gluEndSurface (obj); /* This is never used because of a bug in AIX OpenGL 1.0. gluDeleteNurbsObj (obj); */ glEndList(); glFlush(); } done: DestroyFloatArray (uKnot); DestroyFloatArray (vKnot); DestroyFloatArray (cPoint); if (result == TCL_OK) { char tmp[128]; sprintf (tmp, "%d", dlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } return result; }
/*************************************************************************** DrawRibbon ****************************************************************************/ static void DrawRibbon(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(6*sizeof(GLfloat)*c->size); for(i=0; i < c->size*6; i+=6){ ctrlpts[i] = c->rp_n[i/6].x - comx; ctrlpts[i+1] = c->rp_n[i/6].y - comy; ctrlpts[i+2] = c->rp_n[i/6].z - comz; ctrlpts[i+3] = c->rp_c[i/6].x - comx; ctrlpts[i+4] = c->rp_c[i/6].y - comy; ctrlpts[i+5] = c->rp_c[i/6].z - comz; } GLfloat* uknots = E_MALLOC(sizeof(GLfloat)*(2*c->size+4)); for(i=0; i < 2*c->size+4; i++){ if(i>c->size*2+3){ uknots[i]=uknots[c->size*2+3]; } else{ uknots[i]=i/1.0; } } GLfloat vknots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; glColor3f(0.0, 0.0, 1.0); glLineWidth(2); glEnable(GL_AUTO_NORMAL); glShadeModel(GL_SMOOTH); glPushMatrix(); gluNurbsCallback(nurbs, GLU_ERROR, (GLvoid(*)())nurbsError); gluNurbsProperty(nurbs, GLU_V_STEP, 4); gluNurbsProperty(nurbs, GLU_U_STEP, 4); gluNurbsProperty(nurbs, GLU_CULLING, GL_TRUE); gluNurbsProperty(nurbs, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE); glShadeModel(GL_SMOOTH); gluBeginSurface(nurbs); 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); } gluNurbsSurface(nurbs, //context object c->size*2+4, //number of u-knots uknots, //u-knot pointer 8, //number of v-knots vknots, //v-knot ptr 3, //width of u-control points (u-stride) 3, //width of v-control points (v-stride) ctrlpts, //control point pointer 4, // u-order of the curve (degree+1) 4, // v-order of the curve (degree+1) GL_MAP2_TEXTURE_COORD_2 //type ); gluNurbsSurface(nurbs, //context object c->size*2+4, //number of u-knots uknots, //u-knot pointer 8, //number of v-knots vknots, //v-knot ptr 3, //width of u-control points (u-stride) 3, //width of v-control points (v-stride) ctrlpts, //control point pointer 4, // u-order of the curve (degree+1) 4, // v-order of the curve (degree+1) GL_MAP2_VERTEX_3 //type ); gluEndSurface(nurbs); glPopMatrix(); }
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; }
/*************************************************************************** Draw3dRibbon ****************************************************************************/ static void Draw3dRibbon(int snum){ int i = 0; float comx = 0.0, comy = 0.0, comz = 0.0; float *cp = E_MALLOC(3*sizeof(float)); float *inA = E_MALLOC(3*sizeof(float)); float *inB = E_MALLOC(3*sizeof(float)); float *inC = E_MALLOC(3*sizeof(float)); float *out = E_MALLOC(3*sizeof(float)); 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-1)); GLfloat* tracepts = E_MALLOC(3*sizeof(GLfloat)*c->size-1); for(i=0; i < c->size-1; i++){ if((i) %2){ ctrlpts[i*12] = c->rp_c[i].x - comx; ctrlpts[i*12+1] = c->rp_c[i].y - comy; ctrlpts[i*12+2] = c->rp_c[i].z - comz; } else{ ctrlpts[i*12] = c->rp_o[i].x - comx; ctrlpts[i*12+1] = c->rp_o[i].y - comy; ctrlpts[i*12+2] = c->rp_o[i].z - comz; } inA[0] = c->rp_c[i].x - c->rp_ca[i].x; inA[1] = c->rp_c[i].y - c->rp_ca[i].y; inA[2] = c->rp_c[i].z - c->rp_ca[i].z; inB[0] = c->rp_c[i].x - c->rp_o[i].x; inB[1] = c->rp_c[i].y - c->rp_o[i].y; inB[2] = c->rp_c[i].z - c->rp_o[i].z; cross(cp, inA, inB); normalize(cp); inC[0] = ((c->rp_c[i].x + c->rp_ca[i].x) / 2) - comx; inC[1] = ((c->rp_c[i].y + c->rp_ca[i].y) / 2) - comy; inC[2] = ((c->rp_c[i].z + c->rp_ca[i].z) / 2) - comz; //cross(out, cp, inC); //normalize(out); ctrlpts[i*12+3] = inC[0] + cp[0]; ctrlpts[i*12+4] = inC[1] + cp[1]; ctrlpts[i*12+5] = inC[2] + cp[2]; if((i) %2){ ctrlpts[i*12+6] = c->rp_o[i].x - comx; ctrlpts[i*12+7] = c->rp_o[i].y - comy; ctrlpts[i*12+8] = c->rp_o[i].z - comz; } else{ ctrlpts[i*12+6] = c->rp_c[i].x - comx; ctrlpts[i*12+7] = c->rp_c[i].y - comy; ctrlpts[i*12+8] = c->rp_c[i].z - comz; } ctrlpts[i*12+9] = inC[0] - cp[0]; ctrlpts[i*12+10] = inC[1] - cp[1]; ctrlpts[i*12+11] = inC[2] - cp[2]; tracepts[i] = inC[0]; tracepts[i+1] = inC[1]; tracepts[i+2] = inC[2]; // printf("[%f, %f, %f], [%f, %f, %f] \n", // cp[0], cp[1], cp[2], // inC[0], inC[1], inC[2]); // printf("[%f, %f, %f], [%f, %f, %f], [%f, %f, %f], [%f, %f, %f] \n", // ctrlpts[i], ctrlpts[i+1] ,ctrlpts[i+2], ctrlpts[i+3], ctrlpts[i+4], // ctrlpts[i+5], ctrlpts[i+6], ctrlpts[i+7], ctrlpts[i+8], ctrlpts[i+9], // ctrlpts[i+10], ctrlpts[i+11]); } free(cp); free(inA); free(inB); free(inC); free(out); GLfloat* uknots = E_MALLOC(sizeof(GLfloat)*(c->size+3)); for(i=0; i < c->size+3; i++){ if(i<c->size+1 && i>2){ uknots[i] = uknots[i-1]+1.0; } else if(i<3){ uknots[i] = 0.0; } else{ uknots[i] = uknots[i-1]; } } GLfloat vknots[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; GLfloat* knots = E_MALLOC(sizeof(GLfloat)*(c->size+4)); for(i=0; i < c->size+4; i++){ if(i>c->size+2){ knots[i]=knots[c->size+2]; } else{ knots[i]=i/1.0-i%1; } } glColor3f(0.0, 0.0, 1.0); glEnable(GL_AUTO_NORMAL); glShadeModel(GL_SMOOTH); glPushMatrix(); gluNurbsCallback(nurbs, GLU_ERROR, (GLvoid(*)())nurbsError); gluNurbsProperty(nurbs, GLU_V_STEP, 4); gluNurbsProperty(nurbs, GLU_U_STEP, 4); gluNurbsProperty(nurbs, GLU_CULLING, GL_TRUE); gluNurbsProperty(nurbs, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE); glShadeModel(GL_SMOOTH); gluBeginSurface(nurbs); gluNurbsSurface(nurbs, //context object c->size+3, //number of u-knots uknots, //u-knot pointer 8, //number of v-knots vknots, //v-knot ptr 3, //width of u-control points (u-stride) 3, //width of v-control points (v-stride) ctrlpts, //control point pointer 4, // u-order of the curve (degree+1) 4, // v-order of the curve (degree+1) GL_MAP2_TEXTURE_COORD_2 //type ); gluNurbsSurface(nurbs, //context object c->size+3, //number of u-knots uknots, //u-knot pointer 8, //number of v-knots vknots, //v-knot ptr 3, //width of u-control points (u-stride) 3, //width of v-control points (v-stride) ctrlpts, //control point pointer 4, // u-order of the curve (degree+1) 4, // v-order of the curve (degree+1) GL_MAP2_NORMAL //type ); gluNurbsSurface(nurbs, //context object c->size+3, //number of u-knots uknots, //u-knot pointer 8, //number of v-knots vknots, //v-knot ptr 3, //width of u-control points (u-stride) 3, //width of v-control points (v-stride) ctrlpts, //control point pointer 4, // u-order of the curve (degree+1) 4, // v-order of the curve (degree+1) GL_MAP2_VERTEX_3 //type ); gluEndSurface(nurbs); /* gluBeginCurve(nurbs); gluNurbsCurve(nurbs, //context object c->size+4, //number of knots knots, //knot pointer 3, //width of control points tracepts, //control point pointer 4, //order of the curve (degree+1) GL_MAP1_VERTEX_3 //type ); gluEndCurve(nurbs); */ glPopMatrix(); }