图解opengl曲线和曲面绘制
2016-04-06 11:29
441 查看
VC6 下载
http://blog.csdn.net/bcbobo21cn/article/details/44200205
opengl环境配置
http://blog.csdn.net/bcbobo21cn/article/details/51044614#t4
以下的demo工程
http://pan.baidu.com/s/1kVGmRAJ
void glMap2f(GLenum target,GLfloat u1,GLfloat u2,Glint ustride, Glint uorder, GLfloat v1, GLfloat v2, Glint vstride, Glint vorder, const GLfloat *points);
定义2维求值器。
target指定求值器生成的数值类型。本例中的GL_MAP2_VERTEX_3 指明每一个控制点为x、y、z表示的三个浮点值。
u1,u2指定线性映射。
ustride 指定控制点Rij的起始点和控制点 R(i+1)j的的起始点之间单精度或双精度浮点值的个数。这里i和j分别是u和v控制点索引,它允许控制点装入任意的数据结构中。唯一的限制是对于特定控制点的数值必须存在连续的内存单元。
uorder控制点数组在u轴方向上的维数。
v1,v2指定线性映射v
vstride指定控制点Rij的起始点和控制点 Ri(j+ 1)的起始点之间单精度或双精度浮点值的个数。这里i和j分别是u和v控制点索引,它允许控制点装入任意的数据结构中。唯一的限制是对于特定控制点的数值必须存在连续的内存单元。
vorder控制点数组在v轴方向上的维数。
points 一个指向控制点数组的指针。
glMapGrid定义一维或二维网格。
void glMapGrid2f(Glint un, GLfloat u1, GLfloat u2,Glint vn, GLfloat v1,GLfloat v2);
un 在网格[u1,u2]中的分段数目。
u1,u2 指定整数网格范围 i= 0;i= un的映射。
vn在网格[v1,v2]中的分段数目。
v1,v2 指定整数网格范围 j = 0;j= vn的映射。
glEvalMesh 计算一维或二维点或线网格。
void glEvalMesh2(GLenum mode,Glint i1,Glint i2,Glint j1,Glint j2);
mode 指定是否计算二维点、线或多边形的网格。
i1,i2 分别为网格定义域变量i的第一个和最后一个整数值。
j1,j2分别为网格定义域变量j的第一个和最后一个整数值。
glMapGrid和glEvalMesh用来生成并求取一系列等间隔的网格点,glEvalMesh逐步计算一维或二维网格,他的定义范围由glMap指定。mode决定最终计算的顶点是绘制为点、线还是充实的多边形。
以下分别是两组不同控制点的效果;控制点坐标在代码中;
http://blog.csdn.net/bcbobo21cn/article/details/44200205
opengl环境配置
http://blog.csdn.net/bcbobo21cn/article/details/51044614#t4
以下的demo工程
http://pan.baidu.com/s/1kVGmRAJ
一 使用二维求值器绘制一个曲面
#include <windows.h> #include <GL/GLAUX.h> #include <GL/glut.h> #include <math.h> //GLfloat ctrlpoints[5][5][3] = {{{-2,0,0},{-1,1,0},{0,0,0},{1,-1,0},{2,0,0}}, //{{-2,0,-1},{-1,1,-1},{0,0,-1},{1,-1,-1},{2,0,-1}}, //{{-2,0,-2},{-1,1,-2},{0,0,-2},{1,-1,-2},{2,0,-2}}, //{{-2,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{2,0,-3}}, //{{-2,0,-4},{-1,1,-4},{0,0,-4},{1,-1,-4},{2,0,-4}}}; GLfloat ctrlpoints[5][5][3] = {{{-3,0,0},{-1,1,0},{0,0,0},{1,-1,0},{3,0,0}}, {{-3,0,-1},{-1,1,-1},{0,0,-1},{1,-1,-1},{3,0,-1}}, {{-3,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{3,0,-3}}, {{-3,0,-3},{-1,1,-3},{0,0,-3},{1,-1,-3},{3,0,-3}}, {{-3,0,-4},{-1,1,-4},{0,0,-4},{1,-1,-4},{3,0,-4}}}; GLfloat mat_ambient[] = {0.1,0.1,0.1,1.0}; GLfloat mat_diffuse[] = {1.0,0.6,0.0,1.0}; GLfloat mat_specular[] = {1.0,1.0,1.0,1.0}; GLfloat light_ambient[] = {0.1,0.1,0.1,1.0}; //GLfloat light_diffuse[] = {1.0,1.0,1.0,0.0}; GLfloat light_diffuse[] = {0.2,1.0,0.2,0.0}; GLfloat light_specular[] = {1.0,1.0,1.0,0.0}; GLfloat light_position[] = {2.0,23.0,-4.0,1.0}; void myInit(void) { glClearColor(0.0,0.0,0.0,0.0);//设置背景色 /*为光照模型指定材质参数*/ glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialf(GL_FRONT,GL_SHININESS,60.0); /*设置光源参数*/ glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular); glLightfv(GL_LIGHT0,GL_POSITION,light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); /*enable depth comparisons and update the depth buffer*/ glEnable(GL_DEPTH_TEST); /*设置特殊效果*/ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE); glEnable(GL_BLEND); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glFrontFace(GL_CW); glShadeModel(GL_SMOOTH); glEnable(GL_LINE_SMOOTH); } void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColor3f(0.4,0.4,0.4); glTranslatef(0.0,-1.0,0.0); glRotatef(50.0,1.0,0.0,0.0); glPushMatrix(); /*绘制曲面*/ glEnable(GL_MAP2_VERTEX_3); glMap2f(GL_MAP2_VERTEX_3,0,1,3,5,0,1,15,5,&ctrlpoints[0][0][0]); glMapGrid2f(10.0,0.0,1.0,10.0,0.0,1.0); glEvalMesh2(GL_FILL,0,10.0,0,10.0); glPopMatrix(); glutSwapBuffers(); } void myReshape(GLsizei w,GLsizei h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0,0.0,-5.0); } int main(int argc,char ** argv) { /*初始化*/ glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(400,400); glutInitWindowPosition(200,200); /*创建窗口*/ glutCreateWindow("lighted Bezier surface"); /*绘制与显示*/ myInit(); glutReshapeFunc(myReshape); glutDisplayFunc(myDisplay); /*进入GLUT事件处理循环*/ glutMainLoop(); return(0); }
void glMap2f(GLenum target,GLfloat u1,GLfloat u2,Glint ustride, Glint uorder, GLfloat v1, GLfloat v2, Glint vstride, Glint vorder, const GLfloat *points);
定义2维求值器。
target指定求值器生成的数值类型。本例中的GL_MAP2_VERTEX_3 指明每一个控制点为x、y、z表示的三个浮点值。
u1,u2指定线性映射。
ustride 指定控制点Rij的起始点和控制点 R(i+1)j的的起始点之间单精度或双精度浮点值的个数。这里i和j分别是u和v控制点索引,它允许控制点装入任意的数据结构中。唯一的限制是对于特定控制点的数值必须存在连续的内存单元。
uorder控制点数组在u轴方向上的维数。
v1,v2指定线性映射v
vstride指定控制点Rij的起始点和控制点 Ri(j+ 1)的起始点之间单精度或双精度浮点值的个数。这里i和j分别是u和v控制点索引,它允许控制点装入任意的数据结构中。唯一的限制是对于特定控制点的数值必须存在连续的内存单元。
vorder控制点数组在v轴方向上的维数。
points 一个指向控制点数组的指针。
glMapGrid定义一维或二维网格。
void glMapGrid2f(Glint un, GLfloat u1, GLfloat u2,Glint vn, GLfloat v1,GLfloat v2);
un 在网格[u1,u2]中的分段数目。
u1,u2 指定整数网格范围 i= 0;i= un的映射。
vn在网格[v1,v2]中的分段数目。
v1,v2 指定整数网格范围 j = 0;j= vn的映射。
glEvalMesh 计算一维或二维点或线网格。
void glEvalMesh2(GLenum mode,Glint i1,Glint i2,Glint j1,Glint j2);
mode 指定是否计算二维点、线或多边形的网格。
i1,i2 分别为网格定义域变量i的第一个和最后一个整数值。
j1,j2分别为网格定义域变量j的第一个和最后一个整数值。
glMapGrid和glEvalMesh用来生成并求取一系列等间隔的网格点,glEvalMesh逐步计算一维或二维网格,他的定义范围由glMap指定。mode决定最终计算的顶点是绘制为点、线还是充实的多边形。
以下分别是两组不同控制点的效果;控制点坐标在代码中;
二 opengl绘制Bezier Curve
#include "gl/glut.h" int Line_Count = 80; // 线条数越大 曲面越平滑 // 线条数越小 曲面越粗糙 // 可以从 左下 右下 两条曲线得到对比 // 左上曲线控制点 GLfloat ControlPoints0[4][3] = { { -4.0 , 1.0 , 0.0 } , // 控制点在数组中的顺序决定曲线样式 { -1.0 , 1.0 , 0.0 } , { -1.0 , 4.0 , 0.0 } , { -4.0 , 4.0 , 0.0 } }; // 右上曲线控制点 GLfloat ControlPoints1[4][3] = { { 4.0 , 1.0 , 0.0 } , { 1.0 , 4.0 , 0.0 } , { 1.0 , 1.0 , 0.0 } , { 4.0 , 4.0 , 0.0 } }; // 右下曲线控制点 GLfloat ControlPoints2[4][3] = { { 1.0 , -4.0 , 0.0 } , { 4.0 , -4.0 , 0.0 } , { 1.0 , -1.0 , 0.0 } , { 4.0 , -1.0 , 0.0 } }; // 左下曲线控制点 GLfloat ControlPoints3[4][3] = { { -4.0 , -4.0 , 0.0 } , { -1.0 , -4.0 , 0.0 } , { -4.0 , -1.0 , 0.0 } , { -1.0 , -1.0 , 0.0 } }; void Display( void ) { int i; glClear( GL_COLOR_BUFFER_BIT ); glLoadIdentity(); // 先绘制控制点 再绘制曲线 // 左上曲线 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints0[0][0]); glColor3f( 0 , 0 , 1.0 ); glBegin( GL_POINTS ); for( i = 0 ; i < 4 ; i++ ) { glVertex3fv( ControlPoints0[i] ); } glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin( GL_LINE_STRIP ); for( i = 0 ; i <= Line_Count ; i++ ) { glEvalCoord1f( (GLfloat)i/Line_Count ); } glEnd(); // 右上曲线 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints1[0][0]); glColor3f( 1.0 , 0.0 , 0.0 ); glBegin( GL_POINTS ); for( i = 0 ; i < 4 ; i++ ) { glVertex3fv( ControlPoints1[i] ); } glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin( GL_LINE_STRIP ); for( i = 0 ; i <= Line_Count ; i++ ) { glEvalCoord1f( (GLfloat)i/Line_Count ); } glEnd(); // 右下曲线 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints2[0][0]); glColor3f( 0.0 , 0.0 , 1.0 ); glBegin( GL_POINTS ); for( i = 0 ; i < 4 ; i++ ) { glVertex3fv( ControlPoints2[i] ); } glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin( GL_LINE_STRIP ); for( i = 0 ; i <= Line_Count ; i++ ) { glEvalCoord1f( (GLfloat)i/Line_Count ); } glEnd(); // 左下曲线 Line_Count = 8; // 降低线条数 曲线变粗糙 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ControlPoints3[0][0]); glColor3f( 1.0 , 1.0 , 0.0 ); glBegin( GL_POINTS ); for( i = 0 ; i < 4 ; i++ ) { glVertex3fv( ControlPoints3[i] ); } glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin( GL_LINE_STRIP ); for( i = 0 ; i <= Line_Count ; i++ ) { glEvalCoord1f( (GLfloat)i/Line_Count ); } glEnd(); glFlush(); } void Initialize() { glClearColor( 0.0 , 0.0 , 0.0 , 0.0 ); glShadeModel( GL_SMOOTH ); glEnable(GL_MAP1_VERTEX_3); glEnable( GL_LINE_SMOOTH ); // 平滑线条 glPointSize( 6.0 ); // 把点变大一点 看的清楚 } void Reshape( int Width , int Height ) { glViewport( 0 , 0 , (GLsizei)Width , (GLsizei)Height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if( Width <= Height ) { glOrtho( -5.0 , 5.0 , -5.0 * (GLfloat)Height / (GLfloat)Width , 5.0 * (GLfloat)Height / (GLfloat)Width , -5.0 , 5.0 ); } else { glOrtho( -5.0 * (GLfloat)Width / (GLfloat)Height , 5.0 * (GLfloat)Width / (GLfloat)Height , -5.0 , 5.0 , -5.0 , 5.0 ); } glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); } void main() { glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); glutInitWindowSize( 700 , 700 ); glutInitWindowPosition( 162 , 34 ); glutCreateWindow( "Bezier Curve" ); Initialize(); glutDisplayFunc( Display ); glutReshapeFunc( Reshape ); glutMainLoop(); }
相关文章推荐
- 解决Vista系统OpenGL驱动问题的方法整理
- Delphi下OpenGL2d绘图之画四边形的方法
- Delphi下OpenGL2d绘图之画点的方法
- Delphi下OpenGL2d绘图之初始化流程详解
- Delphi使用OpenGL2d绘图之画图片Bmp的方法
- 通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸
- VC运用OPENGL加载BMP纹理图的实现方法汇总
- java实现OpenGL ES纹理映射的方法
- java基于OpenGL ES实现渲染实例
- OpenGL坐标系介绍
- 【翻译】安卓opengl ES教程之四——添加颜色
- linux下opengl的安装(with qt)
- OpenGL超级宝典笔记——显示列表
- OpenGL超级宝典笔记——顶点数组
- OpenGL生成轮廓
- OpenGL超级宝典笔记——性能比较
- OpenGL超级宝典笔记——顶点缓冲区对象
- OpenGL超级宝典笔记——选择
- OpenGL超级宝典笔记——反馈
- OpenGL超级宝典笔记——遮挡查询