您好,欢迎访问三七文档
当前位置:首页 > 财经/贸易 > 资产评估/会计 > openggl画图初学必看
OpenGL作图非常方便,故日益流行,但对许多人来说,是在微机上进行的,首先碰到的问题是,如何适应微机环境。这往往是最关键的一步,虽然也是最初级的。一般的,我不建议使用glut包.那样难以充分发挥Windows的界面上的功能.下面介绍如何在VC++上进行OpenGL编程。OpenGL绘图的一般过程可以看作这样的,先用OpenGL语句在OpenGL的绘图环境RenderContext(RC)中画好图,然后再通过一个Swapbuffer的过程把图传给操作系统的绘图环境DeviceContext(DC)中,实实在在地画出到屏幕上.下面以画一条Bezier曲线为例,详细介绍VC++上OpenGL编程的方法。文中给出了详细注释,以便给初学者明确的指引。一步一步地按所述去做,你将顺利地画出第一个OpenGL平台上的图形来。一、产生程序框架Test.dswNewProject|MFCApplicationWizard(EXE)|Test|OK*注*:加“”者指要手工敲入的字串二、导入Bezier曲线类的文件用下面方法产生BezierCurve.hBezierCurve.cpp两个文件:WorkSpace|ClassView|TestClasses|右击弹出NewClass|GenericClass(不用MFC类)|CBezierCurve|OK三、编辑好Bezier曲线类的定义与实现写好下面两个文件:BezierCurve.hBezierCurve.cpp四、设置编译环境:1.在BezierCurve.h和TestView.h内各加上:#includeGL/gl.h#includeGL/glu.h#includeGL/glaux.h2.在集成环境中Project|Settings|Link|Object/librarymodule|opengl32.libglu32.libglaux.lib|OK五、设置OpenGL工作环境:(下面各个操作,均针对TestView.cpp)1.处理PreCreateWindow():设置OpenGL绘图窗口的风格cs.style|=WS_CLIPSIBLINGS|WS_CLIPCHILDREN|CS_OWNDC;2.处理OnCreate():创建OpenGL的绘图设备。OpenGL绘图的机制是:先用OpenGL的绘图上下文RenderingContext(简称为RC)把图画好,再把所绘结果通过SwaPBuffer()函数传给Window的绘图上下文DeviceContext(简记为DC).要注意的是,程序运行过程中,可以有多个DC,但只能有一个RC。因此当一个DC画完图后,要立即释放RC,以便其它的DC也使用。在后面的代码中,将有详细注释。intCTestView::OnCreate(LPCREATESTRUCTlpCreateStruct){if(CView::OnCreate(lpCreateStruct)==-1)return-1;myInitOpenGL();return0;}voidCTestView::myInitOpenGL(){m_pDC=newCClientDC(this);//创建DCASSERT(m_pDC!=NULL);if(!mySetupPixelFormat())//设定绘图的位图格式,函数下面列出return;m_hRC=wglCreateContext(m_pDC-m_hDC);//创建RCwglMakeCurrent(m_pDC-m_hDC,m_hRC);//RC与当前DC相关联}//CClient*m_pDC;HGLRCm_hRC;是CTestView的成员变量BOOLCTestView::mySetupPixelFormat(){//我们暂时不管格式的具体内容是什么,以后熟悉了再改变格式staticPIXELFORMATDESCRIPTORpfd={sizeof(PIXELFORMATDESCRIPTOR),//sizeofthispfd1,//versionnumberPFD_DRAW_TO_WINDOW|//supportwindowPFD_SUPPORT_OPENGL|//supportOpenGLPFD_DOUBLEBUFFER,//doublebufferedPFD_TYPE_RGBA,//RGBAtype24,//24-bitcolordepth0,0,0,0,0,0,//colorbitsignored0,//noalphabuffer0,//shiftbitignored0,//noaccumulationbuffer0,0,0,0,//accumbitsignored32,//32-bitz-buffer0,//nostencilbuffer0,//noauxiliarybufferPFD_MAIN_PLANE,//mainlayer0,//reserved0,0,0//layermasksignored};intpixelformat;if((pixelformat=ChoosePixelFormat(m_pDC-m_hDC,&pfd))==0){MessageBox(ChoosePixelFormatfailed);returnFALSE;}if(SetPixelFormat(m_pDC-m_hDC,pixelformat,&pfd)==FALSE){MessageBox(SetPixelFormatfailed);returnFALSE;}returnTRUE;}3.处理OnDestroy()voidCTestView::OnDestroy(){wglMakeCurrent(m_pDC-m_hDC,NULL);//释放与m_hDC对应的RCwglDeleteContext(m_hRC);//删除RCif(m_pDC)deletem_pDC;//删除当前View拥有的DCCView::OnDestroy();}4.处理OnEraseBkgnd()BOOLCTestView::OnEraseBkgnd(CDC*pDC){//TODO:Addyourmessagehandlercodehereand/orcalldefault//returnCView::OnEraseBkgnd(pDC);//把这句话注释掉,若不然,Window//会用白色北景来刷新,导致画面闪烁returnTRUE;//只要空返回即可。}5.处理OnDraw()voidCTestView::OnDraw(CDC*pDC){wglMakeCurrent(m_pDC-m_hDC,m_hRC);//使RC与当前DC相关联myDrawScene();//具体的绘图函数,在RC中绘制SwapBuffers(m_pDC-m_hDC);//把RC中所绘传到当前的DC上,从而//在屏幕上显示wglMakeCurrent(m_pDC-m_hDC,NULL);//释放RC,以便其它DC进行绘图}voidCTestView::myDrawScene(){glClearColor(0.0f,0.0f,0.0f,1.0f);//设置背景颜色为黑色glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslated(0.0f,0.0f,-3.0f);//把物体沿(0,0,-1)方向平移//以便投影时可见。因为缺省的视点在(0,0,0),只有移开//物体才能可见。//本例是为了演示平面Bezier曲线的,只要作一个旋转//变换,可更清楚的看到其3D效果。//下面画一条Bezier曲线bezier_curve.myPolygon();//画Bezier曲线的控制多边形bezier_curve.myDraw();//CBezierCurvebezier_curve//是CTestView的成员变量//具体的函数见附录glPopMatrix();glFlush();//结束RC绘图return;}6.处理OnSize()voidCTestView::OnSize(UINTnType,intcx,intcy){CView::OnSize(nType,cx,cy);VERIFY(wglMakeCurrent(m_pDC-m_hDC,m_hRC));//确认RC与当前DC关联w=cx;h=cy;VERIFY(wglMakeCurrent(NULL,NULL));//确认DC释放RC}7处理OnLButtonDown()voidCTestView::OnLButtonDown(UINTnFlags,CPointpoint){CView::OnLButtonDown(nFlags,point);if(bezier_curve.m_NMAX-1){MessageBox(顶点个数超过了最大数MAX=50);return;}//以下为坐标变换作准备GetClientRect(&m_ClientRect);//获取视口区域大小w=m_ClientRect.right-m_ClientRect.left;//视口宽度wh=m_ClientRect.bottom-m_ClientRect.top;//视口高度h//w,h是CTestView的成员变量centerx=(m_ClientRect.left+m_ClientRect.right)/2;//中心位置,centery=(m_ClientRect.top+m_ClientRect.bottom)/2;//取之作原点//centerx,centery是CTestView的成员变量GLdoubletmpx,tmpy;tmpx=scrx2glx(point.x);//屏幕上点坐标转化为OpenGL画图的规范坐标tmpy=scry2gly(point.y);bezier_curve.m_Vertex[bezier_curve.m_N].x=tmpx;//加一个顶点bezier_curve.m_Vertex[bezier_curve.m_N].y=tmpy;bezier_curve.m_N++;//顶点数加一InvalidateRect(NULL,TRUE);//发送刷新重绘消息}doubleCTestView::scrx2glx(intscrx){return(double)(scrx-centerx)/double(h);}doubleCTestView::scry2gly(intscry){}附录:1.CBezierCurve的声明:(BezierCurve.h)classCBezierCurve{public:myPOINT2Dm_Vertex[MAX];//控制顶点,以数组存储//myPOINT2D是一个存二维点的结构//成员为Gldoublex,yintm_N;//控制顶点的个数public:CBezierCurve();virtual~CBezierCurve();voidbezier_generation(myPOINT2DP[MAX],intlevel);//算法的具体实现voidmyDraw();//画曲线函数voidmyPolygon();//画控制多边形};2.CBezierCurve的实现:(BezierCurve.cpp)CBezierCurve::CBezierCurve(){m_N=4;m_Vertex[0].x=-0.5f;m_Vertex[0].y=-0.5f;m_Vertex[1].x=-0.5f;m_Vertex[1].y=0.5f;m_Vertex[2].x=0.5f;m_Vertex[2].y=0.5f;m_Vertex[3].x=0.5f;m_Vertex[3].y=-0.5f;}CBezierCurve::~CBezierCurve(){}voidCBezierCurve::myDraw(){bezier_g
本文标题:openggl画图初学必看
链接地址:https://www.777doc.com/doc-2847538 .html