Win 95/NT下OpenGL编程原理

2008-02-23 05:35:38来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

----科学计算可视化,电脑动画和虚拟现实是现在电脑图像学的三个热点。而这三个热点的核心都是三维真实感图像的绘制。由于OpenGL(

OpenGraphicsLibrary)具备跨平台性、简便、高效、功能完善,现在已成为了三维图像制作方法中事实上的工业标准。自从WindowsNT3.51在微

机平台上支持OpenGL以后,现在微软公司在Windows95OSR2、WindowsNT4.0中连续性的提供OpenGL研发环境。VisualC 从4.2版本以后已完全支持

OpenGL API,使三维世界的"平民化"已成为必然。

----Windows操作系统对OpenGL的支持

----具备Windows编程经验的人都知道,在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数;用OpenGL作图也是

类似,OpenGL函数是通过"渲染上下文"(RenderingContext简写RC)完成三维图像的绘制。Windows下的窗口和设备上下文支持"位图格式"(

PIXELFORMAT)属性,和RC有着位图结构上的一致。只要在创建RC时和一个DC建立联系(RC也只能通过已建立了位图格式的DC来创建),OpenGL的

函数就能够通过RC对应的DC画到相应的显示设备上。这里更有以下需要注意的方面:

----1.一个线程只能拥有一个渲染上下文(RC),也就是说,用户假如在一个线程内对不同设备作图,只能通过更换和RC对应的DC来完成,而RC在

线程中保持不变。(当然,删除旧的RC后再创建新的是能够的)和此对应,一个RC也只能属于一个线程,不能被不同线程同时共享。

----2.设定DC位图格式等于设定了相应的窗口的位图格式,并且DC和窗口的位图格式一旦确定就不能再改变。这一点只能期望以后的Windows版本改

进了。

----3.一个RC虽然能够更换DC,在任何时刻只能利用一个DC(这个DC称为RC的当前DC),但由于一个窗口能够让多个DC作图从而能够让多个线程利

用多个RC在该窗口上执行OpenGL操作。

----4.现在的Windows下的OpenGL版本对OpenGL和GDI在同一个DC上作图有一定的限制。当使用双缓存用OpenGL产生动画时,不能使用GDI函数向该DC

作图。

----5.不建议用ANSIC在Windows下编写OpenGL程式。这样的程式虽然具备跨平台的可移植性(比如很多SGI的例子程式),但是他们不能利用

Windows操作系统的很多特性,实用价值不大。

----用VC来编写OpenGL程式

----经过上面的分析,用VC来调用OpenGL作图的方法就很显然了。步骤如下:

----1.先配置显示设备DC的位图格式(PIXELFORMAT)属性。这通过填充一个PIXELFORMATDESCRIPTOR的结构来完成(关于PIXELFORMATDESCRIPTOR中

各项数据的意义,请参照VC的帮助信息),该结构决定了OpenGL作图的物理设备的属性,比如该结构中的数据项dwFlags中PFD_DOUBLEBUFFER位假如

没有配置(置1),通过该设备的DC上作图的OpenGL命令就不可能使用双缓冲来做动画。有一些位图格式(PIXELFORMAT)是DC支持的,而有一些DC

就不支持了。所以程式必须先用ChoosePixelFormat来选择DC所支持的和指定位图格式最接近的位图格式,然后用SetPixelFormat配置DC的位图格式



----2.利用刚才的设备DC建立渲染上下文RC(wglCreateContext),使得RC和DC建立联系(wglMakeCurrent)。

----3.调用OpenGL函数作图。由于线程和RC一一对应,OpenGL函数的参数中都不指明本线程RC的句柄(handle)

----4.作图完毕以后,先通过置当前线程的RC为NULL(::wglMakeCurrent(NULL,NULL);),断开当前线程和该渲染上下文的联系,由此断开和DC的

联系。此时RC句柄的有效性在微软自己的文档中也没有讲清楚,所以在后面删除RC的时候要先判断以下RC句柄的有效性(

if(m_hrc)::wglDeleteContext(m_hrc);)。再根据情况释放(ReleaseDC)或删除(DeleteDC)DC

----所附程式说明

----所附的程式用MFC完成了一个简单的OpenGL作图,用OpenGL的辅助库画了一个有光照的实心圆球。OpenGL本身的函数这里就不解释了,仅对用

MFC编OpenGL时需要注意的内容做一个简要的说明:

----1.一旦设定了一个DC的位图格式,该DC所联系的窗口的位图格式随之设定。该窗口若含有子窗口或有兄弟窗口,这些兄弟/子窗口的位图格式

没有设成和对应RC一致的格式,OpenGL在他们上面作图就容易出错。故而OpenGL作图的窗口必须具备WS_CLIPCHILDREN和WS_CLIPSIBLINGS风格,程

序中在主框窗的构造函数中用LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,NULL,NULL);指定了主窗口的风

格。

----2.在ANSIC的OpenGL编程中,由auxReshapeFunc定义配置OpenGL视口大小和作图尺寸的回调函数。在MFC中应该由WM_SIZ消息的处理函数来完成

。在ANSIC的OpenGL编程中,由EauxMainLoop定义作图的回调函数。在MFC中应该由WM_PAINT消息的处理函数来处理。相应的,由OpenGL定义的键盘

、鼠标处理函数都应该由相应的Windows处理函数来响应。

----3.OpenGL自己有刷新背景的函数glClear,故而应禁止Windows刷新窗口背景。否则,当窗口需要重画时,Windows会自动先发送WM_ERASEBKGND

,而缺省的处理函数使用白色的背景刷。当OpenGL使用的背景颜色不是白色时,作图时有一帧白色的闪烁。这种现象在做动画时特别明显。程式中

只需要在WM_ERASEBKGND的消息处理函数中禁止父窗口类的消息处理,简单的返回一个TRUE即可。

----4.由于OpenGL的跨平台性,他必须用操作系统的调色板。所以假如GL_INDEX_MODE作图时,必须用VC自己定义调色板。但是一般情况下,用

GL_RGBA_MODE模式比较方便,很少用到GL_INDEX_MODE模式。

----5.在OpenGL作图期间,RC对应的DC不能删除或释放。

----6.由于OpenGL作图时需要长时间占用DC,所以最好把作图窗口类设成CS_OWNDC。MFC缺省的窗口类风格中没有设这一属性,程式中在主窗口C

类的PreCreateWindow方法中自己注册了一个窗口类,除了设定了CS_OWNDC属性以外,还设定了CS_HREDRAW、CS_VREDRAW和CS_SAVEBITS。设定

CS_HREDRAW、CS_VREDRAW是为了让窗口缩放时产生WM_PAINT消息,修正OpenGL视口和作图尺寸;由于OpenGL作图需要很多计算,设定CS_SAVEBITS是

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 实现窗体的渐变背景

下一篇: 使用双缓冲技术绘制曲线图