opengl

  1. 云栖社区>
  2. 博客>
  3. 正文

opengl

镇水古月 2012-03-19 17:00:00 浏览666
展开阅读全文

引用:http://baike.baidu.com/view/9222.htm#8

OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。

 

目录

概述
特点及功能
现状
扩展
绑定
OpenGL 3.1规范
高级功能
编程入门
展开
 

编辑本段概述

高性能图形算法行业标准

  OpenGL™ 是行业领域中最为广泛接纳的 2D/3D 图形 API, 其自诞生至今已催生了各种计算机平台及设备上的数千优秀应用程序。OpenGL™ 是独立于视窗操作系统或其它操作系统的,亦是网络透明的。在包含CAD、内容创作、能源、娱乐、游戏开发、制造业、制药业及虚拟现实等行业领域中,OpenGL™ 帮助程序员实现在 PC、工作站、超级计算机等硬件设备上的高性能、极具冲击力的高视觉表现力图形处理软件的开发。
  

 

OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL。IRIS GL是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是SGI公司便在IRIS GL的基础上开发了OpenGL。OpenGL的英文全称是“Open Graphics Library”,顾名思义,OpenGL便是“开放的图形程序接口”。虽然DirectX在家用市场全面领先,但在专业高端绘图领域,OpenGL是不能被取代的主角。
 
  OpenGL是个与硬件无关的软件接口,可以在不同的平台如Windows 95Windows NTUnixLinux、MacOS、OS/2之间进行移植。因此,支持OpenGL的软件具有很好的移植性,可以获得非常广泛的应用。由于OpenGL是图形的底层图形库,没有提供几何实体图元,不能直接用以描述场景。但是,通过一些转换程序,可以很方便地将AutoCAD、3DS/3DSMAX等3D图形设计软件制作的DXF和3DS模型文件转换成OpenGL的顶点数组
 
  在OpenGL的基础上还有Open Inventor、Cosmo3D、Optimizer等多种高级图形库,适应不同应用。其中,Open Inventor应用最为广泛。该软件是基于OpenGL面向对象的工具包,提供创建交互式3D图形应用程序的对象和方法,提供了预定义的对象和用于交互的事件处理模块,创建和编辑3D场景的高级应用程序单元,有打印对象和用其它图形格式交换数据的能力。
 
  OpenGL的发展一直处于一种较为迟缓的态势,每次版本的提高新增的技术很少,大多只是对其中部分做出修改和完善。1992年7月,SGI公司发布了OpenGL的1.0版本,随后又与微软公司共同开发了Windows NT版本的OpenGL,从而使一些原来必须在高档图形工作站上运行的大型3D图形处理软件也可以在微机上运用。1995年OpenGL的1.1版本面市,该版本比1.0的性能有许多提高,并加入了一些新的功能。其中包括改进打印机支持,在增强元文件中包含OpenGL的调用,顶点数组的新特性,提高顶点位置、法线、颜色、色彩指数、纹理坐标、多边形边缘标识的传输速度,引入了新的纹理特性等等。OpenGL 1.5又新增了“OpenGL Shading Language”,该语言是“OpenGL 2.0”的底核,用于着色对象、顶点着色以及片断着色技术的扩展功能。
 
  OpenGL 2.0标准的主要制订者并非原来的SGI,而是逐渐在ARB中占据主动地位的3DLabs。2.0版本首先要做的是与旧版本之间的完整兼容性,同时在顶点与像素及内存管理上与DirectX共同合作以维持均势。OpenGL 2.0将由OpenGL 1.3的现有功能加上与之完全兼容的新功能所组成(如图一)。借此可以对在ARB停滞不前时代各家推出的各种纠缠不清的扩展指令集做一次彻底的精简。此外,硬件可编程能力的实现也提供了一个更好的方法以整合现有的扩展指令。
 
  目前,随着DirectX的不断发展和完善,OpenGL的优势逐渐丧失,至今虽然已有3Dlabs提倡开发的2.0版本面世,在其中加入了很多类似于DirectX中可编程单元的设计,但厂商的用户的认知程度并不高,未来的OpenGL发展前景迷茫。

发展历程

  1992年7月,SGI公司发布了OpenGL的1.0版本,随后又与微软公司共同开发了Windows NT版本的OpenGL,从而使一些原来必须在高档图形工作站上运行的大型3D图形处理软件也可以在微机上运用。
 
  1995年OpenGL的1.1版本面市,该版本较1.0性能提高许多,并加入了一些新的功能。包括提高顶点位置、法线、颜色、色彩指数、纹理坐标、多边形边缘标识的传输速度,引入了新的纹理特性等等。
 
  1997年,Windows 95下3D游戏的大量涌现,游戏开发公司迫切需要一个功能强大、兼容性好的3D图形接口,而当时微软公司自己的3D图形接口DirectX 3.0功能却是很糟糕。因而以制作《雷神之锤》等经典3D射击游戏而著名的id公司同其它一些游戏开发公司一同强烈要求微软在Windows 95中加入对OpenGL的支持。微软公司最终在Windows 95的OSR2版和后来的Windows 版本中加入了对OpenGL的支持。这样,不但许多支持OpenGL的电脑3D游戏得到广泛应用,而且许多在3D图形设计软件也可以运用支持OpenGL标准的3D加速卡,大大提高其3D图形的处理速度。
 
  2003年的7月28日,SGI和ARB公布了OpenGL 1.5。OpenGL 1.5中包括OpenGL ARB的正式扩展规格绘制语言“OpenGL Shading Language”。OpenGL 1.5的新功包括:顶点Buffer Object、Shadow功能、隐蔽查询、非乘方纹理等。
 
  2004年8月,OpenGL2.0版本发布~OpenGL 2.0标准的主要制订者并非原来的SGI,而是逐渐在ARB中占据主动地位的3Dlabs。opengl2.0支持OpenGL Shading Language、新的shader扩展特性以及其他多项增强特性。
 
  2008年8月初Khronos工作组在Siggraph 2008大会上宣布了OpenGL 3.0图形接口规范,GLSL1.30 shader语言和其他新增功能将再次未来开放3D接口发展指明方向。
 
  OpenGL 3.0 API开发代号为Longs Peak,和以往一样,OpenGL 3.0仍然作为一个开放性和跨平台的3D图形接口标准,在Shader语言盛行的今天,OGL3.0增加了新版本的shader语言:GLSL 1.30,可以充分发挥当前可编程图形硬件的潜能。同时,OGL3.0还引入了一些新的功能,例如顶点矩阵对象,全帧缓存对象功能,32bit浮点纹理和渲染缓存,基于阻塞队列的条件渲染,紧凑行半浮点顶点和像素数据,四个新压缩机制等等。
 
  2009年3月又公布了升级版新规范OpenGL 3.1,也是这套跨平台免费API有史以来的第九次更新。OpenGL 3.1将此前引入的OpenGL着色语言“GLSL”从1.30版升级到了1.40版,通过改进程序增强了对最新可编程图形硬件的访问,还有更高效的顶点处理、扩展的纹理功能、更弹性的缓冲管理等等。宽泛地讲,OpenGL 3.1在3.0版的基础上对整个API模型体系进行了简化,可大幅提高软件开发效率。
 
  2009年8月Khronos小组发布了OpenGL 3.2,这是一年以来OpenGL进行的第三次重要升级。该版本仍然延续了OpenGL发展的方向让图形程序开发者能在多种操作系统和平台下更好的利用新的GPU功能。OpenGL3.2版本提升了性能表现、改进了视觉质量、提高了几何图形处理速度,而且使Direct3D程序更容易移植为OpenGL。除OpenGL之外,Khronos还将其开发的其它标准进行了协调改进,以求可以在更广泛的领域提供强大的图形功能和计算生态系统,这些标准包括用于并行计算的OpenCL、用于移动3D图形开发的OpenGL ES和用于网络3D开发的WebGL。
 
  2010年7月26日发布OpenGL 4.1和OpenGL OpenGL Shading Language 4.10。OpenGL4.1提高视觉密集型应用OpenCL™的互操作性,并继续加速计算剖面为核心的支持和兼容性第一次推出的OpenGL 3.2,使开发人员能够使用一个简化的API或保留向后兼容现有的OpenGL代码,这取决于他们的市场需求。
 
  Khronos旗下的OpenGL ARB(Architecture Review Board)工作组推出了GLSL 1.5OpenGLShading Language(OpenGL着色语言)的升级版,以及在OpenGL3.2框架下推出了两个新功能,可以让开发者在开发新程序时能够在使用流水线内核特性或兼容性特性之间做出选择,其中兼容性特性会提供与旧版OpenGL之间的兼容性。
 
  2011年8月9日在温哥华举行的SIGGRAPH 2011大会上Khronos发布了新的OpenGL 4.2标准细节,对于支持现有硬件的API加入了部分新的支持特性。和OpenGL 4.1一样,OpenGL 4.2主要应用于DX11级别硬件如NVIDIA GeForce 400/500,Radeon HD 5000/6000系列显卡,不过NVIDIA的开发者社区之前曾经表示部分特性可通过扩展功能在最老支持OpenGL2/DX9级别的硬件上实现。
 

编辑本段特点及功能

  OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual C++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;OpenGL使用简便,效率高。它具有七大功能:
 
  1.建模:OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了复杂的三维物体(球、锥、多面体、茶壶等)以及复杂曲线和曲面绘制函数。
 
  2.变换:OpenGL图形库的变换包括基本变换和投影变换。基本变换有平移、旋转、变比镜像四种变换,投影变换有平行投影(又称正射投影)和透视投 影两种变换。其变换方法有利于减少算法的运行时间,提高三维图形的显示速度。
 
  3.颜色模式设置:OpenGL颜色模式有两种,即RGBA模式和颜色索引(Color Index)。
 
  4.光照和材质设置:OpenGL光有辐射光(Emitted Light)、环境光(Ambient Light)、漫反射光(Diffuse Light)和镜面光(Specular Light)。材质是用光反射率来表示。场景(Scene)中物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。
 
  5:纹理映射(Texture Mapping)。利用OpenGL纹理映射功能可以十分逼真地表达物体表面细节。
 
  6:位图显示和图象增强图象功能除了基本的拷贝和像素读写外,还提供融合(Blending)、反走样(Antialiasing)和雾(fog)的特殊图象效果处理。以上三条可使被仿真物更具真实感,增强图形显示的效果。
 
  7:双缓存动画(Double Buffering)双缓存即前台缓存和后台缓存,简言之,后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。
 
  此外,利用OpenGL还能实现深度暗示(Depth Cue)、运动模糊(Motion Blur)等特殊效果。从而实现了消隐算法。OpenGL设备运用,目前瑞芯微2918芯片和英伟达芯片Tegra2 就是采用OpenGL 2.0技术进行图形处理,而基于瑞芯微2918芯片方案代表是台电T760和微蜂X7平板电脑所采用到。
 

编辑本段现状

  Open GL仍然是唯一能够取代微软对3D图形技术的完全控制的API。它仍然具有一定的生命力,但是Silicon Graphics已经不再以任何让微软不悦的方式推广Open GL,因而它存在较高的风险。游戏开发人员是一个有着独立思想的群体,很多重要的开发人员目前仍然在使用Open GL。因此,硬件开发商正在设法加强对它的支持。Direct3D目前还不能支持高端的图形设备和专业应用; Open GL在这些领域占据着统治地位。最后,开放源码社区(尤其是Mesa项目)一直致力于为任何类型的计算机(无论它们是否使用微软的操作系统)提供Open GL支持。
 
  08年8月正式公布OpenGL3.0版本。并且得到了nv的支持,其官方网站上提供针对N卡的sdk下载。
 
  目前,国内的三维游戏开发技术正处于赶超国外的关键时期,从创意、策划、研究开发与实现,到游戏的运营与维护,都有大量的知识值得学习和摸索。由于 Linux 操作系统平台的大力推广,基于Linux 的各种应用软件也不断壮大,因此基于跨平台图形库的跨平台三维游戏开发也越来越受重视。OpenGL(open graphics library)是一种独立的平台无关的三维图形开发库,在各种语言下进行主框架开发并结合应用OpenGL 函数都可以开发出三维游戏。但是由于框架开发的平台相关性使游戏无法跨平台编译运行,因此glut+OpenGL 的方式成了一种很好的选择。但是在对复杂框架和各种媒体的支持方面,glut 并不理想。在Linux 下可以采用FLTK 等框架平台技术实现包括按钮在内的比较复杂的框架功能,但是需要专门的Linux 开发环境,众多的Window 环境下的KDE 爱好者明显对此无法适从。相反,SDL(Simple DirectMedia Layer)作为免费的跨平台多媒体应用编程接口,已经被人们广泛用于开发二维游戏,其优秀的消息框架支持、文件支持和声音支持等都使得它成为能与微软DirectX 匹敌的最为成熟的技术之一。
 

编辑本段扩展

  当独立厂商创建一种新技术时,OpenGL标准允许它们通过“扩展”的方法提供所扩展的功能。然后一个扩展就分成两部分发布:包含扩展函数原型的头文件和作为厂商的设备驱动。每个厂商有一个用于命名它们的新函数和常量的字母缩写。例如,NVIDIA的缩写(“NV”)用于定义它们的专有函数“glCombinerPara-
 
  meterfvNV()”和它们的常量“GL_NORMAL_MAP_NV”。如果多于一个厂商同意实现相同的扩展功能,那么就用缩写“EXT”。进一步,架构评审委员会可能“祝福”这个扩展,那么这就被称为一个“标准扩展”,使用缩写“ARB”。第一个ARB扩展是GL_ARB_multitexture。根据官方扩展提升路径,多纹理不再是可选实现的ARB扩展,它已经是OpenGL 1.4以后的核心API的一部分。
 
  几个库创建在OpenGL之上,提供了OpenGL本身没有的功能:
 
  1)GLU
 
  2)GLUT
 
  3)GLUI
 
  4)GLEW
 
  5)GLEE
 
  特别是,OpenGL Performer库——由SGI开发并可以在IRIX、Linux和Microsoft Windows的一些版本上使用,构建于OpenGL,可以创建实时可视化仿真程序。
 
  当开发者需要使用最新的OpenGL扩展时,他们往往需要使用GLEW或者是GLEE库提供的功能,可以在程序的运行期判断当前硬件是否支持相关的扩展,防止程序崩溃甚至造成硬件损坏。
 

编辑本段绑定

  为了加强它的多语言和多平台特性,已经用很多语言开发了OpenGL的各种绑定和移植。最值得注意的是,Java3D库已经可以利用OpenGL(另一个选择可能是DirectX)作为它的硬件加速了。OpenGL官方网页[1]列出了用于JavaFortran90、Perl、Pike、PythonAdaVisual Basic的多个绑定。
 

编辑本段OpenGL 3.1规范

  Khronos Group在2009年3月又公布了升级版新规范OpenGL 3.1,也是这套跨平台免费API有史以来的第九次更新。
 
  OpenGL 3.1将此前引入的OpenGL着色语言“GLSL”从1.30版升级到了1.40版,通过改进程序增强了对最新可编程图形硬件的访问,还有更高效的顶点处理、扩展的纹理功能、更弹性的缓冲管理等等。宽泛地讲,OpenGL 3.1在3.0版的基础上对整个API模型体系进行了简化,可大幅提高软件开发效率。
 
  OpenGL 3.1主要新特性:Texture Buffer Objects(纹理缓冲对象)、Uniform Buffer Objects(统一缓冲对象)、Signed Normalized Textures(符号正常化纹理)、Primitive Restart(基本元素重启)、Instancing(实例化)、CopyBuffer API(拷贝缓冲接口)……
 
  与OpenGL 3.1规范同步,OpenGL架构评审委员会(ARB)也发布了一个兼容性扩展,能让开发人员在访问OpenGL 3.1里已经删除的OpenGL 1.x/2.x功能,确保应用程序的全面向下兼容性。
 
  OpenGL 3.1公布后,业界图形厂商很快予以了大力支持。AMD OpenGL主管Suki Samra表示:“AMD全面用户OpenGL API,会在今后的Radeon和FirePro产品驱动程序中支持OpenGL 3.1。”NVIDIA市场营销副总裁Dan Vivoli表示:“NVIDIA承诺尽快部署OpenGL 3.1,我们也很自豪地在规范公布同一天放出了自己的测试版驱动程序。”
 
  市场调研机构Jon Peddie Research预测,OpenGL 3.1规范图形硬件的安装规模将超过1亿。AMD、NVIDIA、S3 Graphics的显卡驱动目前都已经支持OpenGL 3.0。
 

编辑本段高级功能

  OpenGL被设计为只有输出的,所以它只提供渲染功能。核心API没有窗口系统、音频、打印、键盘/鼠标或其它输入设备的概念。虽然这一开始看起来像是一种限制,但它允许进行渲染的代码完全独立于他运行的操作系统,允许跨平台开发。然而,有些整合于原生窗口系统的东西需要允许和宿主系统交互。这通过下列附加API实现:
 
  * GLX - X11(包括透明的网络)
 
  * WGL - Microsoft Windows
 
  * AGL - Apple MacOS
 
  另外,GLUT库能够以可移植的方式提供基本的窗口功能。
 

编辑本段编程入门

  OpenGL作图非常方便,故日益流行,但对许多人来说,是在微机上进行的,首先碰到的问题是,如何适应微机环境。这往往是最关键的一步,虽然也是最初级的。一般的,我不建议使用glut 包.那样难以充分发挥 windows 的界面上的功能.
 
  OpenGL 在VC环境下的编程步骤:
 
  建立基于OpenGL的应用程序框架
 
  创建项目:在file -> New中建立项目,基于单文档,View类基于Cview
 
  添加库:在project->Setting中指定库
 
  初始化:选择View->Class Wizard,打开MFC对话框,添加相应的定义
 
  添加类成员说明
 
  基于OpenGL的程序框架已经构造好,以后用户只需要在对应的函数中添加程序代码即可。
 
  下面介绍如何在 VC++ 上进行 OpenGL 编程。 OpenGL 绘图的一般过程可以看作这样的,先用 OpenGL 语句在 OpenGL 的绘图环境 RenderContext (RC)中画好图, 然后再通过一个 Swap buffer 的过程把图传给操作系统的绘图环境 DeviceContext (DC)中,实实在在地画出到屏幕上.
 
  下面以画一条 Bezier 曲线为例,详细介绍VC++ 上 OpenGL编程的方法。文中给出了详细注释,以便给初学者明确的指引。一步一步地按所述去做,你将顺利地画出第一个 OpenGL 平台上的图形来。
 
  一、产生程序框架 Test.dsw
 
  New Project | MFC Application Wizard (EXE) | "Test" | OK
 
  *注* : 加“”者指要手工敲入的字串
 
  二、导入 Bezier 曲线类的文件
 
  用下面方法产生 BezierCurve.h BezierCurve.cpp 两个文件:
 
  WorkSpace | ClassView | Test Classes| <右击弹出> New Class | Generic Class(不用MFC类) | "CBezierCurve" | OK
 
  三、编辑好 Bezier 曲线类的定义与实现
 
  写好下面两个文件:
 
  BezierCurve.h BezierCurve.cpp
 
  四、设置编译环境:
 
  1. 在 BezierCurve.h 和 TestView.h 内各加上:
 
  #include <GL/gl.h>
 
  #include <GL/glu.h>
 
  #include <GL/glaux.h>
 
  2. 在集成环境中
 
  Project | Settings | Link | Object/library module | "opengl32.lib glu32.lib glaux.lib" | OK
 
  五、设置 OpenGL 工作环境:(下面各个操作,均针对 TestView.cpp )
 
  1. 处理 PreCreateWindow(): 设置 OpenGL 绘图窗口的风格
 
  cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CS_OWNDC;
 
  2. 处理 OnCreate():创建 OpenGL 的绘图设备。
 
  OpenGL 绘图的机制是: 先用 OpenGL 的绘图上下文 Rendering Context (简称为 RC )把图画好,再把所绘结果通过 SwapBuffer() 函数传给 Window 的 绘图上下文 Device Context (简记为 DC).要注意的是,程序运行过程中,可以有多个 DC,但只能有一个 RC。因此当一个 DC 画完图后,要立即释放 RC,以便其它的 DC 也使用。在后面的代码中,将有详细注释。
 
  3. m_hDC是DC的句柄,句柄是一个常量,在程序中不会变化。而m_pDC是DC的指针,是一个不安全的存在,可能导致OpenGL绘制不出图像之类的问题。所以建议用句柄代替指针作参数。
 
  int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
 
  {
 
  if (CView::OnCreate(lpCreateStruct) == -1)
 
  return -1;
 
  myInitOpenGL();
 
  return 0;
 
  }
 
  void CTestView::myInitOpenGL()
 
  {
 
  m_pDC = new CClientDC(this); //创建 DC
 
  ASSERT(m_pDC != NULL);
 
  m_hDC = m_pDC->GetSafeHdc();
 
  if (!mySetupPixelFormat()) //设定绘图的位图格式,函数下面列出
 
  return;
 
  m_hRC = wglCreateContext(m_hDC);//创建 RC
 
  wglMakeCurrent(m_hDC, m_hRC); //RC 与当前 DC 相关联
 
  } //CClient * m_pDC;HDC m_hDC; HGLRC m_hRC; 是 CTestView 的成员变量
 
  BOOL CTestView::mySetupPixelFormat()
 
  {//我们暂时不管格式的具体内容是什么,以后熟悉了再改变格式
 
  static PIXELFORMATDESCRIPTOR pfd =
 
  {
 
  sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
 
  1, // version number
 
  PFD_DRAW_TO_WINDOW | // support window
 
  PFD_SUPPORT_OPENGL | // support OpenGL
 
  PFD_DOUBLEBUFFER, // double buffered
 
  PFD_TYPE_RGBA, // RGBA type
 
  24, // 24-bit color depth
 
  0, 0, 0, 0, 0, 0, // color bits ignored
 
  0, // no alpha buffer
 
  0, // shift bit ignored
 
  0, // no accumulation buffer
 
  0, 0, 0, 0, // accum bits ignored
 
  32, // 32-bit z-buffer
 
  0, // no stencil buffer
 
  0, // no auxiliary buffer
 
  PFD_MAIN_PLANE, // main layer
 
  0, // reserved
 
  0, 0, 0 // layer masks ignored
 
  };
 
  int pixelformat;
 
  if ( (pixelformat = ChoosePixelFormat(m_hDC, &pfd)) == 0 )
 
  {
 
  MessageBox("ChoosePixelFormat failed");
 
  return FALSE;
 
  }
 
  if (SetPixelFormat(m_hDC, pixelformat, &pfd) == FALSE)
 
  {
 
  MessageBox("SetPixelFormat failed");
 
  return FALSE;
 
  }
 
  return TRUE;
 
  }
 
  3. 处理 OnDestroy()
 
  void CTestView::OnDestroy()
 
  {
 
  wglMakeCurrent(m_hDC,NULL); //释放与m_hDC 对应的 RC
 
  wglDeleteContext(m_hRC); //删除 RC
 
  if (m_pDC)
 
  delete m_pDC; //删除当前 View 拥有的 DC
 
  CView::OnDestroy();
 
  }
 
  4. 处理 OnEraseBkgnd()
 
  BOOL CTestView::OnEraseBkgnd(CDC* pDC)
 
  {
 
  // TODO: Add your message handler code here and/or call default
 
  // return CView::OnEraseBkgnd(pDC);
 
  //把这句话注释掉,若不然,Window
 
  //会用白色背景来刷新,导致画面闪烁
 
  return TRUE;//只要空返回即可。
 
  }
 
  5. 处理 OnDraw()
 
  void CTestView::OnDraw(CDC* pDC)
 
  {
 
  wglMakeCurrent(m_hDC,m_hRC);//使 RC 与当前 DC 相关联
 
  myDrawScene( ); //具体的绘图函数,在 RC 中绘制
 
  SwapBuffers(m_hDC);//把 RC 中所绘传到当前的 DC 上,从而
 
  //在屏幕上显示
 
  wglMakeCurrent(m_hDC,NULL);//释放 RC,以便其它 DC 进行绘图
 
  }
 
  void CTestView::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(); //CBezierCurve bezier_curve
 
  //是 CTestView 的成员变量
 
  //具体的函数见附录
 
  glPopMatrix();
 
  glFlush(); //结束 RC 绘图
 
  return;
 
  }
 
  6. 处理 OnSize()
 
  void CTestView::OnSize(UINT nType, int cx, int cy)
 
  {
 
  CView::OnSize(nType, cx, cy);
 
  VERIFY(wglMakeCurrent(m_hDC,m_hRC));//确认RC与当前DC关联
 
  w=cx;
 
  h=cy;
 
  VERIFY(wglMakeCurrent(NULL,NULL));//确认DC释放RC
 
  }
 
  7 处理 OnLButtonDown()
 
  void CTestView::OnLButtonDown(UINT nFlags, CPoint point)
 
  {
 
  CView::OnLButtonDown(nFlags, point);
 
  if(bezier_curve.m_N>MAX-1)
 
  {
 
  MessageBox("顶点个数超过了最大数MAX=50");
 
  return;
 
  }
 
  //以下为坐标变换作准备
 
  GetClientRect(&m_ClientRect);//获取视口区域大小
 
  w=m_ClientRect.right-m_ClientRect.left;//视口宽度 w
 
  h=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 的成员变量
 
  GLdouble tmpx,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);//发送刷新重绘消息
 
  }
 
  double CTestView::scrx2glx(int scrx)
 
  {
 
  return (double)(scrx-centerx)/double(h);
 
  }
 
  double CTestView::scry2gly(int scry)
 
  {
 
  }
 
  附录:
 
  1.CBezierCurve 的声明: (BezierCurve.h)
 
  #include "stdafx.h"
 
  #include <GL/gl.h>
 
  #include <GL/glu.h>
 
  #include <GL/glaux.h>
 
  struct myPOINT2D
 
  {
 
  GLdouble x,y;
 
  };
 
  #define MAX 50
 
  class CBezierCurve
 
  {
 
  public:
 
  myPOINT2D m_Vertex[MAX];//控制顶点,以数组存储
 
  //myPOINT2D 是一个存二维点的结构
 
  //成员为Gldouble x,y
 
  int m_N; //控制顶点的个数
 
  public:
 
  CBezierCurve();
 
  virtual ~CBezierCurve();
 
  void bezier_generation(myPOINT2D P[MAX],int level);
 
  //算法的具体实现
 
  void myDraw();//画曲线函数
 
  void myPolygon(); //画控制多边形
 
  }; 
 
  2. CBezierCurve 的实现: (BezierCurve.cpp)
 
  #include "stdafx.h"
 
  #include "bezierCurve.h"
 
  #define LEVEL 7
 
  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()
 
  {}
 
  void CBezierCurve::myDraw()
 
  {
 
  bezier_generation(m_Vertex,LEVEL);
 
  }
 
  void CBezierCurve::bezier_generation(myPOINT2D P[MAX], int level)
 
  {
 
  //算法的具体描述,请参考相关书本
 
  int i,j;
 
  level--;
 
  if(level<0)return;
 
  if(level==0)
 
  {
 
  glColor3f(1.0f,1.0f,1.0f);
 
  glBegin(GL_LINES);//画出线段
 
  glVertex2d(P[0].x,P[0].y);
 
  glVertex2d(P[m_N-1].x,P[m_N-1].y);
 
  glEnd();//结束画线段
 
  return; //递归到了最底层,跳出递归
 
  }
 
  myPOINT2D Q[MAX],R[MAX];
 
  for(i=0;i <m_N; i++)
 
  {
 
  Q[i].x=P[i].x;
 
  Q[i].y=P[i].y;
 
  }
 
  for(i=1;i<m_N;i++)
 
  {
 
  R[m_N-i].x=Q[m_N-1].x;
 
  R[m_N-i].y=Q[m_N-1].y;
 
  for(j=m_N-1;j>=i;j--)
 
  {
 
  Q[j].x=(Q[j-1].x+Q[j].x)/double(2);
 
  Q[j].y=(Q[j-1].y+Q[j].y)/double(2);
 
  }
 
  }
 
  R[0].x=Q[m_N-1].x;
 
  R[0].y=Q[m_N-1].y;
 
  bezier_generation(Q,level);
 
  bezier_generation(R,level);
 
  }
 
  void CBezierCurve::myPolygon()
 
  {
 
  glBegin(GL_LINE_STRIP); //画出连线段
 
  glColor3f(0.2f,0.4f,0.4f);
 
  for(int i=0;i<m_N;i++)
 
  {
 
  //glVertex2d(m_Vertex.x,m_Vertex.y);
 
  glVertex2d(m_Vertex[i].x,m_Vertex[i].y);
 
  }
 
  glEnd();//结束画连线段
 
  }
 

编辑本段与DirectX的区别

  OpenGL 只是图形函数库。
 
  DirectX包含图形, 声音, 输入, 网络等模块。
 
  OpenGL稳定,可跨平台使用。DirectX仅能用于Windows系列平台,包括Windows Mobile/CE系列以及XBOX/XBOX360。
 
  ----------------------------------------------------------------------------------------------
 
  1995年至1996年,微软实行了一项新计划,以支持在Windows95上运行游戏,目标是把市场扩展到被任天堂和世嘉控制的游戏领域。然而,微软不想用已经在NT上提供的OpenGL技术。微软收购了Rendermorphics,Ltd.并得到他的被称作RealityLab的3D API。经重新整理,微软发布了新的3D API——Direct3D。
 
  微软,推行Direct3D,冻结OpenGL!
 
  微软当时拒绝了在Window95上支持OpenGL。不止如此,微软采取异常手段收回对OpenGL的MCD驱动接口的支持,以致硬件厂商不得不放弃已经进入最后测试的OpenGL驱动。微软的市场部门开始向游戏开发商、硬件厂商、新闻出版机构推销Direct3D,同时排斥OpenGL。
 
  API之战!
 
  Silicon Graphics和很多OpenGL用户都依赖OpenGL创新且高性能的技术。但很明显微软打算用Direct3D代替OpenGL,尽管D3D有很多问题而且不能像OpenGL那样被硬件厂商扩展。Silicon Graphics决定在1996 SIGGRAPH会议上作一项演示。演示证明OpenGL至少和D3D一样快,从而驳倒微软的市场论调。因为OpenGL是业界公认标准,比D3D功能丰富,而且图像质量要高一些,所以演示在计算机图形和游戏开发社区导致了激烈论战。
 
  游戏开发者要求OpenGL和D3D站在同等地位!
 
  当技术和市场问题暴露,强烈的支持OpenGL行动开始了。Doom的开发者John Carmack声明拒绝D3D,Chris Hecker在游戏开发杂志上发表了两套API的全面分析,以微软应放弃D3D为结论。游戏开发者先后两次向微软递交请愿书。第一次由56名首席游戏开发者要求微软发行OpenGL MCD驱动,但未成功,因为会让OpenGL与D3D竞争。第二次的公开信由254人签名开始,截止时达到1400人。微软的回答仍是重申旧市场立场。尽管请愿者清楚的要求两套API同等竞争以促进发展,微软却以增加D3D的投资、更加减少OpenGL的投资为回应。
 
  Fahrenheit——D3D与OpenGL的合并?
 
  Silicon Graphics,Microsoft, HP,Intel达成协议联合开发下一代3D API——Fahrenheit。但不了了之,因为微软的打算是把OpenGL的技术用到D3D里并且以此之名驱除OpenGL的威胁。(估计DirectX 8 Graphics即是剩下微软独自开发的Fahrenheit,吸收了OpenGL的很多东西。)
 
  OpenGL豪气不减当年!
 
  OpenGL依然是唯一能与微软单独控制的D3D对立的API,尽管Silicon Graphics不再以任何微软不能接受的方式推行OpenGL。游戏开发这是独立的,并且很多关键人物在用OpenGL,因此,硬件厂商正努力提高对其支持。D3D仍不能支持高端图像和专业应用,而OpenGL主宰着这些土地。在开放原码社区,Mesa项目正提供独立于微软的OpenGL驱动。
 
  译者注:表面上好像D3D比OpenGL支持更多的功能,其实由于D3D不支持硬件扩展,如硬件全景阴影,硬件渲染顺序无关半透明材质等新技术根本无法使用,而D3D(特指D3D8)本身提供的功能只有一小部分能在使用HAL且硬件不支持时模拟,你要用大量代码分析硬件能力和采取不同策略。
 
 
 

网友评论

登录后评论
0/500
评论
镇水古月
+ 关注