vc+opengl绘制NURBS曲面

    技术2026-06-20  9

    本文回顾了NURBS曲面基本性质,研究了NURBS曲面的绘制,并给出了任意NURBS曲面的绘制代码及示例数据。

    1.NURBS曲面

    1.1 NURBS的两种表示这里只介绍NURBS绘制中需要用到的一些基本知识。通常,一个NURBS曲面F(s,t)包含三个要素:           控制顶点(x,y,z),节点序列(s,t)和权因子(w),或者说是           带权控制顶点(x*w,y*w,z*w,w)和节点序列(s,t)。OpenGL中提供了对两类曲面的绘制:type=4:GL_MAP2_VERTEX_4 控制顶点带权,每个点记为(x*w,y*w,z*w,w)type=3:GL_MAP2_VERTEX_3 控制顶点权都为1,每个点记为(x,y,z)第二种情况就是通常的B样条曲面,本文代码考虑的是第一种情况。

    1.2 NURBS的基本关系式假设曲面F(s,t)在s,t方向阶数分别为sorder,torder,控制网格和节点序列分别为GLfloat ctrlpoints[s_count][t_count][type],  //控制网格GLfloat sknot[sknot_count],                  //s节点序列GLfloat tknot[tknot_count],                  //t节点序列那么,OpenGL中,控制网格和节点序列的大小必须满足sknot_count = s_count + sordertknot_count = t_count + torder

    2. NURBS曲面的绘制

    OpenGL中的gluNurbsSurface()函数是绘制NURBS曲线曲面的关键函数,其函数原型定义如下void gluNurbsSurface( GLUnurbsObj * nobj,    //NURBS曲面对象 GLint sknot_count,       //s方向节点数目 GLfloat * sknot,         //s方向节点数组指针 GLint tknot_count,       //t方向节点数目 GLfloat * tknot,         //t方向节点数组指针 GLint s_stride,          //s方向控制点数据跨度 GLint t_stride,          //t方向控制点数据跨度 GLfloat * ctlarray,      //控制点数组指针 GLint sorder,            //s方向上多项式阶数 GLint torder,            //t方向上多项式阶数 GLenum type              //确定求值器类型);

    该函数的参数包括:

    2.1 NURBS对象: GLUnurbsObj *nobj绘制NURBS曲面之前,必须创建一个NURBS对象并设定其属性,例如nobj = gluNewNurbsRenderer();gluNurbsProperty(nobj , GLU_SAMPLING_TOLERANCE, 20);gluNurbsProperty(nobj , GLU_DISPLAY_MODE, GLU_FILL);[Page]

    2.2 曲线阶数GLint sorder,GLint torder,对应两个方向的阶数

    2.3 节点序列GLint sknot_count,GLfloat * sknot,GLint tknot_count,GLfloat * tknot,需要指定指针,数组大小。

    2.4 控制网格GLfloat * ctlarray,GLint s_stride,GLint t_stride,a)这里,控制网格被保存到一个一维数组里面,所以,如果我们定义控制网格为GLfloat ***ctrlpoints;在非配空间时,我们必须保证整个网格数据保存与一个连续区域里面。b)假设控制网格为ctrlpoints[s_count][t_count][4]如果控制网格以行优先保存进入ctlarray,那么s_stride = 4 * t_countt_stride = 4反之,如果控制网格以列优先保存进入ctlarray,那么s_stride = 4t_stride = 4 * s_count

    2.5 求值器类型GL_MAP2_VERTEX_4GL_MAP2_VERTEX_3

    在本文附带代码中,该函数使用为 gluBeginSurface(m_surface); gluNurbsSurface(m_surface, m_knotsU.m_num, m_knotsU.m_knots, m_knotsV.m_num, m_knotsV.m_knots,  4*m_ctrlPoints.m_col, 4,&(m_ctrlPoints.data[0][0][0]), m_orderU,m_orderV, GL_MAP2_VERTEX_4); gluEndSurface(m_surface);

     

    最新回复(0)