当前位置:天才代写 > tutorial > C语言/C++ 教程 > Win 95/NT下OpenGL编程道理

Win 95/NT下OpenGL编程道理

2017-11-05 08:00 星期日 所属: C语言/C++ 教程 浏览:315

副标题#e#

—-科学计较可视化,计较灵活画和虚拟现实是此刻计较机图形学的三个热点。而这三个热点的焦点都是三维真实感图形的绘制。由于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处理惩罚函数来响应。

#p#分页标题#e#

—-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是为了在OpenGL窗口被粉饰后显现出来时,不发生WM_PAINT动静,用内存存储的图象来填充,从而用空间耗损调换计较时间。

—-7.本措施中没有对OpenGL函数的堕落环境作出处理惩罚。OpenGL堕落伍返回错误码,不会抛出异常;并且在某一个函数堕落今后,后继函数也一般不会呈现异常,只是返回错误码,一不小心就大概忽略某些错误。而对每一个OpenGL函数都做堕落与否的判定较量贫苦,所以编措施时对OpenGL的函数该当很是小心。


#p#副标题#e#

—-参考书籍:

—-《OpenGLProgrammer’sGuide》SGIinc.

—-《OpenGL三维图形措施设计》廖朵朵、张华军著,星球舆图出书社

—-《VisualC++5.0联机辅佐》

—-附措施:

—-措施运行时必需确定OpenGL32.dll、glu.dll、glaux.dll在Windows的System目次下。假如找不到这些文件,可以从Windows95OSR2的呆板上面将这些文件拷贝过来即可。OpenGL运行不需要注册库信息。在VC的STUDIO中运行措施时,工程文件中必需插手OpenGL.H、glu.h、glaux.h以及OpenGL.lib、glu.lib、glaux.lib,这些文件由VC自带。
----主窗口类界说(OpenGLWnd.h):
s#if !defined(AFX_OPENGLWND_H__3FB1AB28_0E70
_11D2_9ACA_48543300E17D__INCLUDED_)
#define AFX_OPENGLWND_H__3FB1AB28_0E70_11D2
_9ACA_48543300E17D__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include < afxwin.h >
#include "SimpleGLApp.h"
#include "resource.h"
// OpenGLWnd.h : header file
//
///////////////////////////////////////
//////////////////////////////////////
// COpenGLWnd frame
class COpenGLWnd : public CFrameWnd
{
DECLARE_DYNCREATE(COpenGLWnd)
public:
COpenGLWnd();
// protected constructor used by dynamic creation
protected:
HGLRC m_hrc;
CClientDC *m_pDC;
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COpenGLWnd)
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
/

 

    关键字:

天才代写-代写联系方式