真实感场景绘制(附源码)

首先给出绘制效果图:

说明:

本系统绘制了一个真实感的三维场景,并实现场景漫游。使用按键↑、↓、←、→或W、S、A、D控制运动方向,PgDn和PgUp可以改变观察者的高度,鼠标控制转向,按键‘F’可以打开和关闭“雾气”,Esc退出程序。

本场景中绘制了墙壁与地面、天空、石柱、箱子、玻璃球、雪人、雾等对象,下面将依次分析它们的设计思路,这里将使用相同绘制技术的对象放到一起说明。

1、 墙壁、地面、箱子

它们的基本操作对四边形的纹理映射,将一幅纹理图的四个顶点坐标分别映射到四边形的四个顶点上即可。OpenGL就自动通过插值填充多边形内部的纹理。由于在OpenGL中纹理坐标是一个点的属性,故需要在绘制点之前指定该点的纹理坐标。另外在绘制四边形时要保证绘制顺序的一致,这里统一采用逆时针顺序绘制。纹理坐标范围在[0,1]之间,坐标超过1则采用重复的方式(OpenGL默认处理方式)。这样可以在映射时按四边形的比例设置纹理坐标,从而防止纹理图过度拉伸造成的变形。一个四边形的纹理映射步骤为:

glBindTexture(GL_TEXTURE_2D,texture[0]);

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f); glVertex3f(30.0f,0.0f, -170.0f);

glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f,0.0f, -150.0f);

glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f,20.0f,-150.0f);

glTexCoord2f(0.0f, 1.0f); glVertex3f(30.0f,20.0f,-170.0f);

glEnd();

实验效果如下:

图1.墙壁、地面、箱子

2、 石柱、雪人

石柱和雪人都属于二次几何体的绘制和纹理映射,其中雪人由圆柱、球体、圆盘、圆锥构成。OpenGL提供了这些基本几何体的绘制函数,而且在纹理映射时我们采用自动生成纹理坐标的方法,所以这一部分工作量其实很少。另外,为了给雪人的身体、鼻子等部位设置颜色时,我们需要关闭纹理映射、并更改材质的属性(物体的颜色是由光源和材质共同作用的结果)。对于石柱,我们加上了绕自身局部坐标Y轴的匀速旋转。实验效果如下:

图2.雪人             图3.石柱

我们使用Glut库提供的如下函数绘制二次几何体:

gluCylinder:绘制圆柱和圆柱

gluSphere:绘制球体

gluDisk:绘制圆盘

使用gluQuadricTexture设置自动计算纹理坐标。

3、 玻璃球

在绘制玻璃球时,为了在球面上反射出周围的场景,我们使用了环境映射。由于我们能够在三维场景中漫游,这就需要球面上反射出的场景是随着视点移动而变化的,这一需求可以利用“渲染到纹理”(RTT)技术实现。其基本思想是:首先绘制出环境中的所有物体(除了该玻璃球),接着将绘制得到的场景图制作成纹理,在绘制该玻璃球时将此纹理图贴在球面上即可。

我们使用的核心函数是glCopyTexImage2D,该函数可以将帧缓存中的颜色值复制到纹理缓存中。实验发现该函数性能较低,会拖慢整个程序的速度,为了平衡绘制质量和速度,可以只拷贝一部分像素值。实验效果如下:

图4.玻璃球

4、 雾气

OpenGL中提供了完整的雾化接口,我们只需要选择合适的雾气的混合因子、密度、颜色、起始位置等。我们的雾气设置如下:

GLfloat fogColor[4]={0.5f, 0.5f, 0.5f, 0.5f};

glFogi(GL_FOG_MODE,GL_EXP2);//模式

glFogfv(GL_FOG_COLOR,fogColor);//颜色

glFogf(GL_FOG_DENSITY, 0.004f);//密度

glFogf(GL_FOG_START, 5.0f);//开始距离

glFogf(GL_FOG_END, 300.0f);//结束距离

glHint(GL_FOG_HINT,GL_NICEST);//雾化效果

实验效果如下:

图5.雾气

5、 天空

天空包含云、星星、闪电三个对象。我们要实现的目标是:云在空中飘动、且能够遮盖住空中的星星,每间隔一段时间都会有闪电和雷声。

天空的绘制主要使用了颜色混合技术。首先将星星的纹理图映射到天空,为了实现云朵覆盖住星星,我们使用了如下技巧:制作一个关于云图(图6)的二值图像(图7),其中有云的部分为黑色、无云的部分为白色。将该二值图像作为“掩模”与星星图进行混合,并设置混合因子glBlendFunc (GL_DST_COLOR,GL_ZERO),该设置可以将星星图中对应“掩模”黑色的部分置为黑色、对应“掩模”白色的部分保留原色。接着再将云图映射至天空,并更改混合因子glBlendFunc(GL_ONE, GL_ONE),该设置实现源色与目的色相加。至此已经实现云对星星的遮盖,另外,在进行颜色混合时需要打开OpenGL的颜色混合功能,且要关闭深度测试功能。

图6.云图                         图7.二值图

为了实现云的飘动,我们在设置云图纹理坐标时添加一个变量,该变量从0递增至1,超过1时做减1操作,这样就可以模拟云的移动。如下的roll即为该变量:

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 3.0f-roll);glVertex3f(-50.0f, 100.0f, -300.0f);

glTexCoord2f(1.0f, 3.0f-roll);glVertex3f( 50.0f, 100.0f, -300.0f);

glTexCoord2f(1.0f, 0.0f-roll);glVertex3f( 50.0f, 100.0f,  300.0f);

glTexCoord2f(0.0f, 0.0f-roll);glVertex3f(-50.0f, 100.0f,  300.0f);

glEnd();

每绘制一定帧数后,我们将一幅闪电纹理图映射到天空,使用简单的相加混合,且在首次绘制闪电时调用音频播放函数,播放一段雷声,音频调用函数为PlaySound。实验效果如下:

图8.天空

源码下载

时间: 2024-10-24 23:28:00

真实感场景绘制(附源码)的相关文章

C#版无人驾驶汽车(附源码)

一,简单问题复杂化: 100公里/1小时的速度,在日常生活中是比较常见的速度,把它转换为其它单位: 100公里/1小时 ≈ 28米/1秒 100公里/1小时 ≈ 2800厘米/秒 如果想要无人驾驶汽车达到厘米级的位移监测.探测器扫描路况时,每秒上传2800次数据给PC机.若一辆汽车有10个探测器,就意味着每秒的并发量为2.8W次/秒. 2.8W次/秒的并发量,在网站上肯定会采用分布式,缓存,读写分离,集群技术,关键还有这个数据的存储,到底用二维数据库,还是用NOSQL.这些问题是不是让你很头痛?

C#编程总结(七)数据加密——附源码

C#编程总结(七)数据加密——附源码 概述 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人窃取.阅读的目的. 该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程.加密建立在对信息进行数学编码和解码的基础上.加密类型分为两种,对称加密与非对称加密,对称加密双方采用共同密钥.非对称加密,这种加密方式存在两个密钥,一个是公共密钥(对外公开),一种

精选12个时尚的 CSS3 效果【附源码下载】

精选12个时尚的 CSS3 效果[附源码下载] 这里是精选的12个很炫的 CSS3 效果.CSS3 是对 CSS 规范的一个很大的改善和增强,它使得 Web 开发人员可以很容易的在网站中加入时尚的效果.以前很多需要编写复杂的 JavaScript 代码才能实现的效果,如今只需要简单的写几句 CSS3 代码就能实现. 超炫的 CSS3 页面切换动画效果 今天我们想与大家分享一组创意的页面切换熊效果集合.我们已经在示例中罗列了一组动画,可以被应用到页面切换过程中,创造出很有趣的导航效果. 源码下载 

ANDROID自定义视图——仿瀑布布局(附源码)

简介: 在自定义view的时候,其实很简单,只需要知道3步骤: 1.测量--onMeasure():决定View的大小 2.布局--onLayout():决定View在ViewGroup中的位置 3.绘制--onDraw():如何绘制这个View. 第3步的onDraw系统已经封装的很好了,基本不用我们来操心,只需要专注到1,2两个步骤就中好了. 第一步的测量,可以参考:(ANDROID自定义视图--onMeasure,MeasureSpec源码 流程 思路详解) 第二步的布局,可以参考:(AN

opencvbase 实现opencv打开摄像头和初步处理等效果操作(附源码)

// TwoCameraOnTimer2Dlg.cpp : 实现文件 /* CvMat, Mat, IplImage之间的互相转换 IpIImage -> CvMat CvMat matheader; CvMat * mat = cvGetMat(img, &matheader); CvMat * mat = cvCreateMat(img->height, img->width, CV_64FC3); cvConvert(img, mat) IplImage -> Mat

(转)干货|这篇TensorFlow实例教程文章告诉你GANs为何引爆机器学习?(附源码)

干货|这篇TensorFlow实例教程文章告诉你GANs为何引爆机器学习?(附源码) 该博客来源自:https://mp.weixin.qq.com/s?__biz=MzA4NzE1NzYyMw==&mid=2247492203&idx=5&sn=3020c3a43bd4dd678782d8aa24996745&chksm=903f1c73a74895652ee688d070fd807771e3fe6a8947f77f3a15a44a65557da0313ac5ad592c

让你心动的 HTML5 & CSS3 效果【附源码下载】

这里集合的这组 HTML5 & CSS3 效果,有的是网站开发中常用的.实用的功能,有的是先进的 Web 技术的应用演示.不管哪一种,这些案例中的技术都值得我们去探究和学习. 超炫的 HTML5 粒子效果进度条 我喜欢粒子效果作品,特别是那些能够应用于实际的,例如这个由 Jack Rugile 基于 HTML5 Cavnas 编写的进度条效果.看着这么炫的 Loading 效果,即使让我多等一会也无妨:) 源码下载      在线演示 使用 CSS3 打造一组质感细腻丝滑的按钮 CSS3 引入了

Matlab.NET混合编程技巧之——直接调用Matlab内置函数(附源码)

原文:[原创]Matlab.NET混合编程技巧之--直接调用Matlab内置函数(附源码) 在我的上一篇文章[原创]Matlab.NET混编技巧之--找出Matlab内置函数中,已经大概的介绍了matlab内置函数在混合编程中的优点,并通过程序找出了matlab中的大部分内置函数,当然更多人关心是如何像我所说得那样,不用直接编译,就直接在C#中调用这些内置函数.本文就带你揭开这些谜团. 声明,这篇文章是需要一点点混合编程基础的,基本概念和过程要懂一点,如果能简单成功混编一个简单的计算或者绘图例子

C#版的无人驾驶汽车(附源码)

一,简单问题复杂化: 100公里/1小时的速度,在日常生活中是比较常见的速度,把它转换为其它单位: 100公里/1小时 ≈ 28米/1秒 100公里/1小时 ≈ 2800厘米/秒 如果想要无人驾驶汽车达到厘米级的位移监测.探测器扫描路况时,每秒上传2800次数据给PC机.若一辆汽车有10个探测器,就意味着每秒的并发量为2.8W次/秒. 2.8W次/秒的并发量,在网站上肯定会采用分布式,缓存,读写分离,集群技术,关键还有这个数据的存储,到底用二维数据库,还是用NOSQL.这些问题是不是让你很头痛?

cocos2d-x 委托模式的巧妙运用——附源码(二)

转载请注明出处:http://blog.csdn.net/hust_superman/article/details/38292265,谢谢. 继上一篇将了委托类的具体实现后,这篇来将一下如何在游戏中使用实现的委托类.也就是如何在游戏中来调用委托类来完成一些功能.具体的应用场景和应用层会在下面介绍. 先来看一看游戏demo实现的具体图片,demo比较简单,但是资源齐全,拿到源码后可以在源码的基础上继续完善demo做出一款真正的游戏.好了,老规矩,先上图再说: 游戏中点击播放按钮后会进入游戏主界面