OpenGL由已知控制点绘制模拟曲面地形转载请注明出处主要要点:1.将离散的数据点网格化曲面2.对3d模型的鼠标控制,如虚拟球的实现由已知控制点通过曲面拟合方法,将不规则的数据分布转换成规则的网格分布,然后绘制三维地形曲面图。即如图所示:数据规则网格化(简称网格化)。网格化实际是一种曲面拟合方法。关于曲面拟合算法有很多,下面我们采用曲面样条方法实现网格化。我们定义曲面样条函数:下面为c++/c代码:3D_MAP.cpp1#includeiostream2#includetools.h3#includeGrids.h4#include3dmap.h56usingnamespacestd;78//3D_MAP.cpp:定义控制台应用程序的入口点。910intxFar=0.0f,yFar=0.0f,zFar=0.0f;11intwWidth=1300,wHeight=700;12intoldX,oldY;13boolgIsStartTrackBall=false;14boolgIsMoveMap=false;15TrackBalltrackball;16_3dMapmap;1718voiddisplayEvent()19{20glClearColor(0,0,0.1f,1);21glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);2223glMatrixMode(GL_MODELVIEW);24glLoadIdentity();25glTranslatef(xFar,yFar,zFar);2627trackball.makeRolate();28map.drawMap();2930glFlush();31glutSwapBuffers();//交换缓存32}3334voidmouseMoveEvent(intx,inty)35{36if(gIsStartTrackBall)37{38trackball.MouseMove(x,y);39glutPostRedisplay();40}41if(gIsMoveMap)42{43xFar-=oldX-x;44yFar+=oldY-y;45oldX=x;46oldY=y;47glutPostRedisplay();48}49}50//鼠标事件函数51voidmouseEvent(intbutton,intstate,intx,inty)52{53if(button==GLUT_LEFT_BUTTON)54{55if(state==GLUT_DOWN)56{57oldX=x;58oldY=y;59trackball.setXY(x,y);60gIsStartTrackBall=true;61}62elseif(state==GLUT_UP)63{64oldX=x;65oldY=y;66gIsStartTrackBall=false;67}68glutPostRedisplay();69}elseif(button==GLUT_RIGHT_BUTTON)70{71if(state==GLUT_DOWN)72{73oldX=x;74oldY=y;75gIsMoveMap=true;76}elseif(state==GLUT_UP)77{78oldX=x;79oldY=y;80gIsMoveMap=false;81}82}83}84//窗体尺寸变化事件85voidresizeEvent(intw,inth)86{87wWidth=w;88wHeight=h;89zFar=0.0f;90xFar=0.0f;91yFar=0.0f;92glViewport(0,0,w,h);93glMatrixMode(GL_PROJECTION);94glLoadIdentity();95h=h0?h:1;96floataspect=(float)w/(float)h;97gluPerspective(45,aspect,1.0,1500.0);98glTranslatef(0,0,-300.0f);99100trackball.resize();101102103glutPostRedisplay();104}105voidprocessSpecialKeys(intkey,intx,inty){106if(key==101)107{108zFar+=4;109glutPostRedisplay();110}111if(key==103)112{//113zFar-=4;114glutPostRedisplay();115}116printf(key:%d\n,key);117}118119voidMenuFunc(intdata)120{121switch(data)122{123case1:124map.setLineOrFill();break;125default:break;126}127glutPostRedisplay();128}129voidglInit()130{131glShadeModel(GL_FLAT);//SMOOTH//GL_FLAT132glClearColor(1.0f,1.0f,1.0f,1.0f);133glClearDepth(1.0f);134135glEnable(GL_NORMALIZE);136137glEnable(GL_DEPTH_TEST);138glAlphaFunc(GL_GREATER,0);139glDepthFunc(GL_LEQUAL);140glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);141142glEnable(GL_BLEND);143glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);144145glEnable(GL_POINT_SMOOTH);146glEnable(GL_LINE_SMOOTH);147glEnable(GL_POLYGON_SMOOTH);148149glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);//Makeroundpoints,notsquarepoints150glHint(GL_LINE_SMOOTH_HINT,GL_NICEST);//Antialiasthelines151glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);152153154//glClearColor(1.0,1.0,1.0,1.0);//窗口背景设置为白色155glMatrixMode(GL_MODELVIEW);//设置投影参数156157glEnable(GL_COLOR_MATERIAL);158glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);159160}161162intmain(intargc,char*argv[])163{164map.initMap();165166glutInit(&argc,argv);//初始化GLUT167glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH|GLUT_MULTISAMPLE);//设置显示模式168glutInitWindowPosition(0,0);//设置显示窗口的左上角位置169glutInitWindowSize(wWidth,wHeight);//设置窗口的长和高170glutCreateWindow(3DMap);//创造显示窗口171172glInit();//开始初始化过程173glutReshapeFunc(resizeEvent);174glutDisplayFunc(displayEvent);175glutMouseFunc(mouseEvent);176glutSpecialFunc(processSpecialKeys);177glutMotionFunc(mouseMoveEvent);178glutCreateMenu(MenuFunc);179glutAddMenuEntry(填充/网格,1);180glutAttachMenu(GLUT_MIDDLE_BUTTON);181182glutMainLoop();//显示所有并等候183184getchar();185return0;186}tools.htools.h中定义了TrackBall类,用于对3D模型进行鼠标的旋转,世界中心点的移动等控制1#includecmath2#includegl/glut.h34usingnamespacestd;56structGPoint3d{7doublemX,mY,mZ;8doublex(){returnmX;}9doubley(){returnmY;}10doublez(){returnmZ;}11voidsetX(doublex){mX=x;}12voidsetY(doubley){mY=y;}13voidsetZ(doublez){mZ=z;}14voidset(doublex,doubley,doublez){mX=x;mY=y;mZ=z;}15};1617classTrackBall18{19intOldX;20intOldY;21doublemMatrix[16];22public:23TrackBall(){}24//向量的点积25doubledotMult(GPoint3dv1,GPoint3dv2);26//向量的叉积27GPoint3dcrossMult(GPoint3dv1,GPoint3dv2);28//将鼠标二维点映射为球面向量(用于鼠标追踪球)29GPoint3dgMousePtToSphereVec(intx,inty,intw,inth);30voidmakeRolate();3132voidMouseMove(intx,inty);33voidresize()34{35glGetDoublev(GL_MODELVIEW_MATRIX,mMatrix);//返回当前模型矩阵36}37voidsetXY(intx,inty){OldX=x;OldY=y;}38voidsetP(double*v)//{x1,y1,z1,x2,y2,z2,x3,y3,z3}39{40GPoint3dv1,v2,v3;41v1.setX(v[3]-v[0]);42v1.setY(v[4]-v[1]);43v1.setZ(v[5]-v[2]);4445v2.setX(v[6]-v[0]);46v2.setY(v[7]-v[1]);47v2.setZ(v[8]-v[2]);4849v3=crossMult(v1,v2);5051glNormal3f(v3.x(),v3.y(),v3.z());52}53};5455doubleTrackBall::dotMult(GPoint3dv1,GPoint3dv2)56{57doubleangle;58angle=v1.x()*v2.x()+v1.y()*v2.y()+v1.z()*v2.z();59returnangle;60}61GPoint3dTrackBall::crossMult(GPoint3dv1,GPoint3dv2)62{63GPoint3dv;64v.setX(v1.y()*v2.z()-v1.z()*v2.y());65v.setY(v1.z()*v2.x()-v1.x()*v2.z());66v.setZ(v1.x()*v2.y()-v1.y()*v2.x());67returnv;68}6970//将鼠标二维点映射为球面向量(用于鼠标追踪球)71GPoint3