﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-蕙麓-随笔分类-计算机图像学(OpenGL)</title><link>http://www.cppblog.com/oxionghui/category/19656.html</link><description>Email:oxionghui@gmail.com</description><language>zh-cn</language><lastBuildDate>Sat, 14 Jul 2012 06:05:43 GMT</lastBuildDate><pubDate>Sat, 14 Jul 2012 06:05:43 GMT</pubDate><ttl>60</ttl><item><title>基于OpenGL的3D天空仿真（转）</title><link>http://www.cppblog.com/oxionghui/archive/2012/06/09/178204.html</link><dc:creator>蕙麓</dc:creator><author>蕙麓</author><pubDate>Sat, 09 Jun 2012 08:27:00 GMT</pubDate><guid>http://www.cppblog.com/oxionghui/archive/2012/06/09/178204.html</guid><wfw:comment>http://www.cppblog.com/oxionghui/comments/178204.html</wfw:comment><comments>http://www.cppblog.com/oxionghui/archive/2012/06/09/178204.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/oxionghui/comments/commentRss/178204.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/oxionghui/services/trackbacks/178204.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体; font-size: 14px; line-height: 24px; "><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">文章来自：<a href="http://www.c-cnc.com/dz/news/news.asp?id=18622">http://www.c-cnc.com/dz/news/news.asp?id=18622</a><br />在进行3D场景渲染时，天空是必不可少的因素。对于3D天空的模拟在视景仿真系统、计算机游戏、三维动画中有着广泛的应用。但是，目前对于天空的仿真还存在很多不足，一些模拟方法中存在实现复杂、计算耗时、图像分辨力不高，真实感不强且只能生成静态图像等问题。本文在研究了前人仿真天空算法的基础上，利用目前3D图形行业中流行的OpenGL技术和有被誉为"大自然的几何学"美称的分形理论，提出了一种更加简单实用的仿真3D天空的方法，可以仿真出具有动态效果和不同天气的3D天空，绘制速度快，真实感强。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">l构造天空模型</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">1．1 OpenGL技术［1.2］</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">OpenGL作为一套图形标准，由数百个功能函数组成，提供了访问图形硬件的所有特性，其严格按照计算机图形学原理设计而成，符合光学和视觉的原理，非常适合可视化仿真系。其优势在于：首先，在OpenGL中，允许视景对象用图形方式表达；其次，OpenGL通过光照处理能表达出物体的三维特性，其光照模型是整体光照模型。可视化仿真图像的颜色体现着物体与视点以及光源之间的空间位置关系，具有很强的三维效果。此外，为弥补图形方法难于生成复杂自然背景的不足，OpenGL提供了对图像数据的使用方法，即直接对图像数据读、写和拷贝，或者把图像数据定义为纹理与图形方法结合在一起生成视景图像以增强效果。本文研究了基于OpenGL技术的3D天空仿真，使得算法易于实现，并且有很好的可视化效果。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">1．2 传统模型</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">在传统的3D游戏中，对于天空的仿真，程序员往往从实时简单的角度出发，采用非常简化的天空模型，通常包括以下3种方法［3-5］：用一种接近天空的淡蓝色来清除背景；采用天空盒(skyBox)的方法：即首先绘制一个多边形，然后进行立方体纹理贴图；八棱锥天空模型：定义一个天顶，以这个顶点为中心绘制一圈三角形扇，然后进行纹理映射。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">这3种方法都具备了实时性，方法简单的优点，但同时也存在明显的不足，第一种方法绘制的天空效果看起来太平面化，简单粗糙，逼近度不高。第二种方法对纹理的要求非常高，如果纹理使用得不好，在一个比较大的多边形上的纹理就容易产生拉伸变形的副作用。此外，雾化设置也会产生问题，如果雾的设置靠近观察点，则天空的颜色会变淡甚至没有。第三种方法有明显的天顶。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">显然，在如今这种对3D场景仿真要求越来越高的时代，这些方法已经不适应时代的要求，需要寻求一种渲染速度快，真实感强，有一定交互能力的3D天空模型。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">1．3 半球型天空模型</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">地球是球型的，所以天空像半个球一样笼罩在大地之上。在用计算机仿真3D天空时，半球型天空模型显然符合真实世界的天空模型。利用数学中的球面方程，可以建立如下模型：<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283625.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">P是球面上一点，R为球的半径。在球面坐标系下方程改写为：<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283654.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">对于一个半球．&#966;为纬度，其变化范围是O&#8804;&#966;&#8804;90&#176;；&#952;为经度，其变化范围是O&#8804;&#952;&#8804;360&#176;。采用球型(DOme)的方法，比起采用盒子(BOx)的方法，有很多优点。首先由于球形方法绘制的天空具有更多的顶点，雾化效果可以绘制得更加均匀［5］。同时也可以实时改变单个顶点的颜色，这样可以获得一些非常好的效果，如一天不同时刻的太阳光。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">半球型天空模型也存在不足：<br /><br />(1)顶点数目过多，影响渲染速度。<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283721.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">N为所需要绘制的顶点总数；&#9651;&#966;，&#9651;&#952;为绘制球型天顶的顶点经纬度间隔，值越小、网格越密，绘制越精细。由于采用OpenG技术中的三角形带绘制(GL-TRIANGLE一STRIP)，每次绘制4个顶点，每个顶点被绘制4次，故需要乘以4。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">(2)三角函数的运算过多。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">在单一场景的渲染中不会影响渲染速度，但在复杂的3D场景中，渲染速度的劣势会体现出来。因为在计算机中三角函数的运算较之加、减、乘、除等运算要慢的多。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">1．4 曲面天空模型</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">为保持球型天空模型的优势并弥补该算法的不足，本文研究了一种渲染速度更快的曲面天空模型，该模型如图1所示。<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/20083128381.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">该模型类似于将一个经过细分的平面的4个角点向下拉，形状看上去像一个撑开的降落伞，将他罩在场景之上，可以模拟3D天空。曲面的长度为S为：<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283839.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">顶点坐标(x,y,z)的计算公式为：</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">&nbsp;</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283911.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">其中&#9651;s为曲面细分间隔；j，i为循环参数。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">曲面天空模型仍然可以用OpenGL技术中的三角形带((GLTRIANGLE_STRIP)绘制，但他避免了三角函数的运算，且顶点数目比相同精度的球型天空模型少，故增加了渲染速度。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">2 天空云图</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">2．1 分形云图</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">分形［4］方法建造的物体模型结构精细、算法控制相对简单，适合于描绘云、树等结构精细的物体。本文利用分形理论中的插值算法产生静态天空云图纹理，算法如下：</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">(1)在平面上划分正方形网格n&#215;n，随机给A1，A2，A3，A4这4个角点的颜色。如图2所示。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">(2)计算中点值，B1＝(A1+A2+A3+A4)&#215;0．25+&#958;&#215;scale，其中&#958;是一个随机量；Scale一(1／2)H(标度)H即Hurst指数，他也是分形维数D的度量：D一2一H，如图3所示。<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831283941.jpg"  alt="" />&nbsp;<img src="http://www.c-cnc.com/dz/news/file/2008-3/20083128402.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">(3)根据A1，A4，B1点和网格外一虚拟点，重复第(2)节，得到边中点c1的颜色值。同理，可计算出C2，C3，C4边中点的颜色值。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">(4)递归步骤(2)，(3)，使其正方形网格不断细化，直到达到预期的递归深度。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">以上步骤中，正方形初始点的颜色是随机赋予的，但正方形网格内的所有点不是随机分布的。通过采用分形插值算法，使得网格内相邻点之间建立了某种联系，从而使生成体内部过渡得更加自然。这样，通过分形插值算法，得到一个2维数组，将数组中的每一个元素值看成是云的不透明度数据。最小数组值代表最蓝色，天空中云最少的部分，最大的值代表最白色，天空中云最重的部分。分析数组并生成蓝天白云纹理图如图4所示。<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831284036.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">2．2 纹理映射</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">纹理映射技术［1.2］也叫纹理贴图技术(Texture Map-ping)，与建造模型的方法相比，在摸拟物体表面细节方面，纹理映射是一个较有效的方法。景物表面纹理细节的模拟在真实感图形合成技术中起着非常重要的作用，这种将景物表面纹理细节的模拟称为纹理映射技术。现在，纹理映射已经成为三维图形世界中最为常用的技术之一，其数学过程十分复杂，但OpenGL已对其进行处理，于是编程者可以利用几个函数就可以完成纹理贴图。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">执行纹理贴图的步骤可以概括为：定义纹理贴图；控制纹理；说明纹理贴图方式；激活纹理映射；定义纹理坐标等。在一个球面上进行纹理映射是比较复杂的，采用不同的映射方式将产生不同的问题。如果采用平面映射的方式将在连续处产生纹理拉伸现象，如果采用球面映射，最大的问题是在球面的极点产生纹理的聚集现象，对于好的纹理，这种现象可以缩减到最小。根据球面几何知识，可以得到纹理坐标的具体计算公式：<br /><img height="40" src="http://www.eccn.com/xsj07/image/xsj080843_10.jpg" width="250"  alt="" /><br />加上1／2的原因是为了使U，V坐标的值处于(0．0，1．0)范围内。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">3 动态仿真</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">本文采用定时器技术和改变纹理矩阵坐标的方法实现云的流动效果。首先定义一个100 ms的定时器，每隔100ms纹理坐标改变一次。其次，使用多重纹理来添加一个单独的云彩贴图，通过变换纹理矩阵坐标实现流动。变换纹理坐标的方法是先将当前矩阵类型设置为纹理矩阵(GL-TEXTURE)，然后调用glTranslate()，glRotate()和glScale()函数实现坐标的平移、旋转和缩放。这样，云就可以缓慢地在天空中移动。此外，通过添加按键响应函数，在函数体中利用()penGL的模型变换函数，如glRotate()，可以以任意角度旋转3D天空，达到用户与3D场景的交互的效果。</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">4仿真结果</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">本仿真实验在CPU为P4，主频为1．7 GHz，内存为256 M，集成显卡上完成。仿真结果如图5～图8所示。天空中的云彩可以沿球形天空缓慢移动，客户可以通过上下左右键旋转3D天空。该模型在实时3D场景仿真中可以笼罩在场景之上，有很好的3D效果，并且真实感强。采用半球型天空模型的帧速率为250～285 f/s；采用曲面型天空模型的帧速率为324～340 f／s，在保证真实感和交互性的前提下，从渲染速度上看曲面天空模型优于半球型天空模型。<br /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/20083128414.jpg"  alt="" />&nbsp;<img src="http://www.c-cnc.com/dz/news/file/2008-3/200831284124.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">&nbsp;</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; "><img src="http://www.c-cnc.com/dz/news/file/2008-3/200831284147.jpg"  alt="" />&nbsp;<img src="http://www.c-cnc.com/dz/news/file/2008-3/20083128429.jpg"  alt="" /></p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">5 结 语</p><p style="margin-top: 12px; margin-right: 0px; margin-bottom: 12px; margin-left: 0px; ">本仿真系统的软件平台为VC++6．O，通过OpenGL图形库函数实现可视化仿真。利用球形方程、平面方程、三角函数等几何原理建立各种3D天空模型，运用分形理论中的插值算法编写天空纹理，并通过OpenGL函数进行三角形带绘制天空框架，纹理映射技术，映射出具有真实效果的3D天空。从仿真结果来看，真实感强，实时性好，此外，通过按键响应函数，可以以任意角度旋转，任意高度升降3D天空，交互性强，非常适合3D游戏的户外场景仿真。</p></span> <img src ="http://www.cppblog.com/oxionghui/aggbug/178204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/oxionghui/" target="_blank">蕙麓</a> 2012-06-09 16:27 <a href="http://www.cppblog.com/oxionghui/archive/2012/06/09/178204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenGL程序框架 </title><link>http://www.cppblog.com/oxionghui/archive/2012/05/22/175743.html</link><dc:creator>蕙麓</dc:creator><author>蕙麓</author><pubDate>Tue, 22 May 2012 03:54:00 GMT</pubDate><guid>http://www.cppblog.com/oxionghui/archive/2012/05/22/175743.html</guid><wfw:comment>http://www.cppblog.com/oxionghui/comments/175743.html</wfw:comment><comments>http://www.cppblog.com/oxionghui/archive/2012/05/22/175743.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/oxionghui/comments/commentRss/175743.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/oxionghui/services/trackbacks/175743.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: OpenGL.h,OpenGL.cpp主要是图形处理相关的操作。main.cpp主程序&nbsp;OpenGL.h:&nbsp;interface&nbsp;for&nbsp;the&nbsp;OpenGL&nbsp;class.&nbsp;2&nbsp;//&nbsp;3&nbsp;/////////////////////////////////////////////////////////...&nbsp;&nbsp;<a href='http://www.cppblog.com/oxionghui/archive/2012/05/22/175743.html'>阅读全文</a><img src ="http://www.cppblog.com/oxionghui/aggbug/175743.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/oxionghui/" target="_blank">蕙麓</a> 2012-05-22 11:54 <a href="http://www.cppblog.com/oxionghui/archive/2012/05/22/175743.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>