计算机图形学报告——太阳系_第1页
计算机图形学报告——太阳系_第2页
计算机图形学报告——太阳系_第3页
计算机图形学报告——太阳系_第4页
计算机图形学报告——太阳系_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Solar System 计计算算机机图图形形学学 课课程程报报告告 文档编号:报告名称:算法设计 编 写:谢天添 0743111185编写日期: 2009-12 指导老师:李征审核日期: 1图形学基本原理.3 1.1几何变换相关原理.3 1.2几何图形像素化相关原理.3 1.3光照模型相关原理.3 2系统界面与操作说明(阐述如何操作你的软件).3 2.1系统界面与图形显示示例.3 2.2操作说明(配合图示进行说明).4 3源程序:.8 3.1太阳系概述:.8 3.2数据收集:.8 3.3类设计:.9 3.3.1Main Class .9 3.3.2辅助类:.9 3.3.3模块增强类:.10 3.4功能设计:.11 3.4.1反锯齿:.11 3.4.2帧率.12 3.4.3大气云层.13 3.4.4太阳特效.14 3.4.4.1流动.14 3.4.4.2Glow:.15 3.4.5光属性.15 3.5代码实现:.15 3.5.1Star 类:.15 3.5.2Galaxy 类:.23 3.5.3Cskysphere 类:.27 3.5.4C4_Antiliasing 类:.34 3.5.5ChaseCamera 类: .37 3.5.6C4_Selector 类:.39 3.5.7main 函数.40 4小结.48 4.1总结在原理理解、程序设计中所遇到的困难是如何解决的,可以举出 1 至 2 个例子。.48 4.2总结本门课程所学到的知识。.48 5参考文献.49 6运行截图.49 1图形学基本原理图形学基本原理 1.1几何变换相关原理几何变换相关原理 几何变换所涉及坐标系和变换如下: Object coordinates-modelview Matrix eye coordinatesprojectionmatrix clip coordinate-perspectiveMatrix normalized device coordinates-viewportTransformation window coordinates. 1.2几何图形像素化相关原理几何图形像素化相关原理 几何图形像素化就是几何图形经过一系列的变换后储存在帧缓存中的图形,经过其他 的一些操作后,将输出到屏幕坐标。由于光栅化前这些坐标是浮点连续的。而屏幕坐标系 是离散的像素点。几何图形像素画就是将这些连续的图形变为离散的像素点集并且确保正 确的渲染。如果没有该步骤,几何图形是不能渲染到使用像素的屏幕坐标。 1.3光照模型相关原理光照模型相关原理 点光源:向四面八方发射光线的单点。 聚光灯光源:从特定地点射向特定方向的光源。 平行光源:从无限远处射来的点光源。 面光源:从一个平面发出平行光的光源。 最终的每个像素 color 输出为几何点在光珊化中环境光,漫反射和镜面光的叠加。 2系统界面与操作说明(阐述如何操作你的软件)系统界面与操作说明(阐述如何操作你的软件) 2.1系统界面与图形显示示例系统界面与图形显示示例 左下角:camera 的数据,当前帧率。 2.2操作说明(配合图示进行说明)操作说明(配合图示进行说明) 在该太阳系中,提供以下几个键: F:摄像机到目标物体的距离增加 5。 R:摄像机到目标物体的距离减少 5。 :开启或关闭反锯齿。 鼠标左键按住不放时,左右上下移动改变摄像机相对目标物体的位置, 但是不改变距离 选取一个星球,摄像机自动飞向该星球: 未操作前截图: 按 F 后 按 R: 鼠标左键不放左上拖动 选取一个星球,摄像机自动飞向该星球: 过程图片: 到达图片: 目前在反据此模式下,点击“” 关闭反锯齿: 这里只有通过帧数的改变显示出改变 3源程序:源程序: 3.1太阳系概述:太阳系概述: 太阳系 (Solar System)就是我们现在所在的恒星系统。它是以太阳为中心,和所有 受到太阳引力约束的天体的集合体:8 颗行星冥王星已被开除、至少 165 颗已知的卫星, 和数以亿计的太阳系小天体。这些小天体包括小行星、柯伊伯带的天体、彗星和星际尘埃。 广义上,太阳系的领域包括太阳、4 颗像地球的内行星、由许多小岩石组成的小行星带、 4 颗充满气体的巨大外行星、充满冰冻小岩石、被称为柯伊伯带的第二个小天体区。在柯 伊伯带之外还有黄道离散盘面、太阳圈和依然属于假设的奥尔特云。 模拟太阳系不仅仅是完成作业,也能让我们更近一步的了解太阳系,拓广知识面,对 行星的运行有基本的感性和理性感知。增加我们对宇宙探索的渴望,可能培养出又一批天 文学家。 3.2数据收集:数据收集: 要模拟太阳系的运行首先需要他们的数据,这里我收集了“9”大行星,太阳,月球 数据如下: 行星 a(AU) 轨道 周期 (yr)i(deg)e 自转周期 自转轴 倾斜(度)质量(地球) 半径 (地球) 水星 0.3870.2417.000.20458.8d00.0550.383 金星 0.7230.6143.400.007244d-20.8150.949 地球 1.0001.0000.000.01723.9h23.51.0001.000 火星 1.521.881.900.09424.6h28.20.1070.533 木星 5.2011.91.300.0499.9h3.131811.2 土星 9.5829.42.500.05710.7h26.795.29.45 天王星 19.283.70.780.04617.2h-82.114.54.01 海王星 30.1163.71.780.01116.1h28.317.13.88 冥王星 39.224817.20.2446.39d1220.0020.19 103kmd1020kgkm 月球 38527.3 18.3 -28.6Va0.0557301738 a=轨道半长轴 i=轨道倾角 e=轨道偏心率 1AU=149600000km 质量和半径是对于地球的相应值的相对值 地球质量=5.977*1027 次方 地球赤道半径=6378km 以上每列数据是每个星球必有的。通过这些属性,以地球为标准,获取行星的运动方程就 可以模拟出行星的运动轨迹和位置等数据。现在还需要的外部数据就是:每个行星的纹理。 在纹理选择上。我使用的是分辨率为 256*256 RBGA 的 tga 格式文件。使用自己编写的一 个类 resourceImage 派生于 C4_Image.读取该纹理。以在渲染时使用。 在这个程序中,假设所有星球的运动轨迹是圆。而非椭圆。这样就简化了程序在编写时的 复杂度。并且假设程序不考虑万有引力。 3.3类设计:类设计: 在该太阳系中类图关系如下: 3.3.1Main Class baseGameEntity:提供的最主要功能为:为每一个实体提供一个独特的 ID.以便为绑定纹理, 选择,提供方便,以免冲突。 MovingEntity:提供实体的 up,front,speed 等参数。 Galaxy:是星系的抽象体,他具有个天空球(CSkySphere)和他所包含的星球(star)的集合。 Star:是一个星球的抽象实体。他具有表中的属性,除此还有一个 CSkySphere。这里 CSkySphere 作为该星球的球体渲染时的纹理和顶点信息。由于每个星球可能也有他的卫星, 他的卫星也可能还有卫星。所以每个 star 中都有一个 star 的集合. ChaseCamera:提供围绕一个星球旋转的功能; 提供调整到星球距离的功能; C4_Image:从文件加载 32 位,24 位或 8 位 tga 格式的纹理。保存到一个 unsigned char 数组 中。 ResourceImage:对 C4_Image 进行扩展。可以加载DDS_DX1_decals_compressed,DDS_DX1_CUBMAP 两类文件。但是由于 DDS_DX1_CUBMAP 显示分辨率太低,所以就没有用 cubmap.这使得没有使用 cubmap 而 是使用自己写的天空球来模拟环境纹理。 3.3.2辅助类:辅助类: 类图如下: 这 6 个类为辅助类,每一个需要渲染的物体都有一个 C4_Material. matrix3D matrix4D,vector3D,vector4D 提供基本的几何运算,不用多说。 C4_Light 提供创建 8 个光源实例。在程序中使用了 1 个光源。 3.3.3模块增强类:模块增强类: 所谓模块增强类,就是提供更好的图形显示或更多的功能。类图如下: 该太阳系提供 3 个增强模块,3 个功能: 1) ,C4_Selector :对派生于 baseGameEntity 的物体提供鼠标选择功能。 2) ,C4_Antialiasing :提供全局的 antialiasing,反锯齿(反走样) ,使用的是 glaccum. 3), C4_CgEffect :提供高级顶点,片段编程。基于 NVADIA 的 Cg2.0.(opengl version:=1.4) 以上为对程序的一些类的简介。不过大体就这 15 个类。 (2,3 运行截图请参看附录) 3.4功能设计:功能设计: 3.4.1反锯齿:反锯齿: 在太阳系中使用了 2 组 jitter 系数,让 projection matrix 产生微小位移,然后渲染物体。 将两次渲染的结果累计到缓存区,然后渲染出来。使用前后对比: 前 后 使用的样本数据: double j22=0.25,0.75,0.75,0.25; (参考 the red book 累积缓冲区) 在使用 glCalllist 调用 一个非常冗余的 圆的渲染时 在开启反锯齿后 在同样的情况下,每 秒的帧数只有 6 帧/秒,而改进之后 帧数达到了 9 帧/秒左右。 在原来情况下每个顶点 要被渲染 4 次。改进后每个点被渲染 2 次。如果要进一步 的该进,就要使用 索引。由于时间关系就不再优化。以下为改进前和改进后的性能对比。 改进前: 改进后 对比。 由该表可以看出 glAccum 所使用的时间之巨大,也可以让我们了解到渲染时顶点越少越好。 3.4.2帧率帧率 但是如果不开启 反锯齿,改进前和改进后的区别基本上没有。都是 20 帧左右。但是, 不过为什么无论我怎么调,该帧数都不变。例如将太阳系中的行星删除掉 80,禁用光源, 但是帧数依然不变。最终发现 是 glutTimerFunction 中设置问题。开始设置的 1/24.0。而后 当我设置成 1/40.0 时。帧数变为 32 帧左右。当我继续减少该值的时候。无反锯齿下,最多 可以达到 66 帧,反锯齿下反而有所降低到 89 帧。但是此时又有一个问题。当帧数载 66 帧左右的时候。有某个瞬间尤其不稳定可能突然渲染时间降低到 0.0001 以下或突然上升到 0.1s。此时.就需要一个采样的队列对时间进行采样使得物体和镜头的移动更加平滑。在程 序中我使用了一个最简单的方法,求最近 n 次的平均帧长。这里应该设置一个比率。越早 的数据权重应该越低。以下为部分代码。 #define FRAMESAMPLESIZE 100 int curframeSample=0; float frameFRAMESAMPLESIZE=0; curframeSample=(curframeSample+1)%FRAMESAMPLESIZE; framecurframeSample=time_eclipse; updateTime=0; for(int i=0;im_pAtmosphere-Render(); glDisable(GL_ALPHA_TEST); if(!bEnable) glDisable(GL_BLEND); if(bCullEnable) glEnable(GL_CULL_FACE); glDepthMask(true); 截图如下: 从左到右分别为:太阳,月球,金星,地球。 由于没找到好的云图片,效果就只有这样了。不过这依然还需要改进。 3.4.4太阳特效太阳特效 太阳应该看起来有一点流动效果,并且太阳的周围应该还有飞出的火焰,也就是类似 于光晕的光圈。这就有 2 个问题。1,流动,2,光圈(glow) 。 3.4.4.1流动流动 流动如果在常规的管道流程中来生成,对太阳的每个顶点进行变换或纹理。是比较耗 费时间的。所以这里在程序中使用了 NVIDIA 的 cg(支持 opengl1.4 及其以上) 。我的电脑 最多支持 opengl1.4,所以就只有用 cg 所支持的 fragment shader 和 vertex shader.这里只是对 顶点进行放缩。 float displacement = scaleFactor * 0.5 *sin(position.y * frequency * time)+1; float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0); float4 newPosition = position + displacement * displacementDirection; oPosition = mul(modelViewProj, newPosition); 这里,对于每个顶点,都会在其法向量方向进行震动。具有相同 y 值的顶点会有相同的幅度,在法线 方向的长度相同。这样又 y 值的不一样,在视觉上就有起伏感觉。而在 modelviewproj 构造时会有一个根 据时间增加的旋转值。这样看起来每个顶点都在起伏并且移动。在贴了纹理后就有点流体的感觉。 这是在使用 cg 时的太阳 这是在没有使用时的图片 但是太阳的反锯齿由于 cg 的特性(在渲染 cg 前的所有其他非 cg 的函数操作都对其没有作 用)而变没了。 3.4.4.2Glow: 目前我在 opengl 下还没弄出来不过班上有同学在 dx 下已经弄出来了。 3.4.5光属性光属性 如果你查看附录的图像时,你会发现及时是很远的行星向光面都很亮,因为光的衰减 函数如下: F(x)=1/(1+0.001x); Y 2.0 x 0 1000AU 3.5代码实现:代码实现: 只将关键代码罗列如下: 3.5.1Star 类:类: /* Star.h */ #pragma once #include movingentity.h #include SkySphere.h #include C4_Material.h #include /* a star has a skysphere to show its outside pattern */ class Star : public MovingEntity private: CSkySphere*m_sSphere; C4_Material m_c4Mat; std:vector *m_pvSatellite; char m_szStarName10; CSkySphere *m_pAtmosphere; public: Star(int id, float inMass,float inRadiu, float inAU,float inYr,float inDeg,float inE, const char*texFileName, float inRPeriod=0,float inRotInc=0, const char*starName=NONE); Star(void); public: /those method should be implemented virtual void Update(float ftime_eclipse); virtual void Render(); virtual bool HandleMessage(const Telegram CSkySphere* getSkySphere()constreturn m_sSphere; void setMaterial(const C4_Material void addSatellite(Star*inStar)if(inStar)m_pvSatellite-push_back(inStar); Star* getSatelliteStar(int id); void setChildEnvMode(int model); protected: float m_fAU;/轨道半长轴以AU为单位1AU=149600000km float m_fYr;/轨道周期以地球的周期比。地球:.0 float m_fDeg;/轨道倾斜角deg float m_fE;/偏心率shaft eccentricity float m_fRotationPeriod;/自转周期 float m_fRotInc;/rotational inclination 自转轴倾角 /mass /radius will be handle down in the base. /simple rotation float m_fTheta; float m_fSelfRotationTheta; void RenderSatellite(); public: float getAU()constreturn m_fAU; void setAU(const float float getYr()constreturn m_fYr; void setYr(const float float getDeg()constreturn m_fDeg; void setDeg(const float float getE()constreturn m_fE; void setE(const float float getRotationPeriod()constreturn m_fRotationPeriod; void setRotationPeriod(const float float getRotInc()constreturn m_fRotInc; void setRotInc(const float ; /* Star.cpp */* #pragma warning (disable:4996) #include Star.h #include utility.h #include Matrix4D.h #include ChaseCamera.h #include #include C4_math.h #include C4_Antialiasing.h #ifdef CG_ENABLE static C4_CgEffect * GlowEffect=NULL; #endif float getDegJump(const Vector3D if(length=2500) return 6; else if(length200*200) return 12; else if(lengthRender(); #endif Star:Star(int id, float inMass,float inRadiu, float inAU,float inYr,float inDeg,float inE, const char*texFileName, float inRPeriod,float inRotInc, const char*starName) :MovingEntity(id) m_fSelfRotationTheta=0; this-setMass(inMass); this-setRadius(inRadiu); this-setAU(inAU); this-setYr(inYr); this-setE(inE); this-setDeg(inDeg); this-setRotationPeriod(inRPeriod); this-setRotInc(inRotInc); m_sSphere=new CSkySphere(); m_sSphere-loadSkyImage(texFileName);/this will compile one /set other parameters /double a=this-getRadius(); /double b=sqrt(1-this-getE()*this-getE(); this-setPos(Vector3D(this-getAU()*10,0,0); m_fTheta=0; /* 替换法则: 二次曲线f(x,y)=ax2+by2+cx+dy+e=0上某一点(x,y),过(x,y)的切线方程为: axx+byy+c(x+x)/2+d(y+y)/2+e=0 */ m_pvSatellite=new std:vector(); strncpy(this-m_szStarName,starName,strlen(starName)10?10:strlen(starName); if(0=strcmp(starName,earth) m_pAtmosphere=new CSkySphere(); m_pAtmosphere-loadSkyImage(image/atmosphere/atmosphere.tga); if(0=strncmp(starName,sun,3) Init(); Star:Star(void) if(this-m_sSphere) delete m_sSphere; if(m_pAtmosphere) delete m_pAtmosphere; if(m_pvSatellite) std:vector:iterator it=this-m_pvSatellite-begin(); std:vector:iterator end=this-m_pvSatellite-end(); while(it!=end) delete (*it); it+; delete m_pvSatellite; void Star:Update(float ftime_eclipse) double mat16; float theta=10*ftime_eclipse/(this-getYr(); m_fTheta+=theta; if(this-getRotationPeriod()!=0) m_fSelfRotationTheta+=1000*ftime_eclipse/(this-getRotationPeriod(); glPushMatrix(); / glLoadIdentity(); glRotated(this-getDeg(),1.0,0,0);/lielie glRotated(m_fTheta,0,1,0); glTranslated(this-getAU()*10,0,0); glRotated(-m_fTheta,0,1,0); glGetDoublev(GL_MODELVIEW_MATRIX,mat); Matrix4D tmp;tmp.setGLArrayMatrix(mat); Vector4D pos(tmp*Vector4D(); if(pos.getV3()=Vector3D() if(this-getPos()=Vector3D() this-setPos(pos.getV3(); else printf(calculation lurkn); else this-setPos(pos.getV3(); /-satellite updata- std:vector:iterator it=this-m_pvSatellite-begin(); std:vector:iterator end=this-m_pvSatellite-end(); while(it!=end) (*it)-Update(ftime_eclipse); it+; glPopMatrix(); int jmp=m_sSphere-getDegPerJump(); Vector3D p=CameraMgr-getPos()-this-getPos(); int m=getDegJump(p); if(jmp!=m) jmp=m; if(this-getRadius()7 #ifdef CG_ENABLE void TestStar(Star* a); #endif void Star:Render() static float time=0.5; time+=0.01; #ifdef CG_ENABLE if(0=strncmp(this-m_szStarName,sun,3) rotateM.setMatrix3D(getRotationMatrix(Vector3D(0,1,0),C4_degToRad(m_fSelfRotationTheta) ); rotateBack.setMatrix3D(getRotationMatrix(Vector3D(1,0,0),C4_degToRad(-90); Matrix3D sm=CameraMgr-getViewMatrix(); glPushMatrix(); double mat_m16; glLoadIdentity(); gluLookAt(sm.M00,sm.M01,sm.M02, sm.M10,sm.M11,sm.M12, 0,1,0); glGetDoublev(GL_MODELVIEW_MATRIX,mat_m); viewM.setGLArrayMatrix(mat_m); glPopMatrix(); modelViewProjMNoRotate=ProjectM*viewM; modelViewProjM=modelViewProjMNoRotate*rotateM*rotateBack; /:glViewport(0,0,400,300); m_pCgEffect-StartFgEffect(); m_pCgEffect-StartVsEffect(); m_pCgEffect-EnableTexture(sun); cgSetMatrixParameterdr(this-m_pCgEffect- getVsParam(modelViewProj),modelViewProjM.toArrayMatrix(); float eyePosition3=CameraMgr-getPos().x,CameraMgr-getPos().y,CameraMgr- getPos().z; cgSetParameter3fv(m_pCgEffect-getVsParam(eyePosition),eyePosition); Vector4D v=ProjectM*viewM*Vector4D(1,0,0,1); cgSetParameter3dv(m_pCgEffect-getVsParam(lightPosition),v.toArrayVect(); cgSetParameter1d(m_pCgEffect-getVsParam(time),time); m_pCgEffect-UpdateFsParam(); m_pCgEffect-UpdateVsParam(); if(this-isSelectEnable() glLoadName(this-getID(); :C4_checkForCgError(before rendering scene); this-m_sSphere-Render(); m_pCgEffect-DisableTexture(sun); m_pCgEffect-EndVsEffect(); m_pCgEffect-EndFgEffect(); /TestStar(this); /:this/:this isis commentedcommented forfor glowglow isis justjust underunder constructionconstruction /:can/:can notnot bebe called.called. return; #endif ErrorCheck1(before render star); glPushMatrix(); /glLoadIdentity(); glRotated(this-getDeg(),1.0,0,0);/lielie /glTranslated(1,0,0); glRotated(m_fTheta,0,1,0); glTranslated(this-getAU()*10,0,0); glRotated(-m_fTheta,0,1,0); ErrorCheck1(before render satellite); this-RenderSatellite(); /self rotation if(this-getRotationPeriod()!=0) glRotated(this-getRotInc(),0.0,0,1.0); glRotated(this-m_fSelfRotationTheta,0,1.0,0); glScalef(this-getRadius(),this-getRadius(),this-getRadius(); ErrorCheck1(before apply material); this-m_c4Mat.Apply(); if(this-isSelectEnable() glLoadName(this-getID(); /*if(0=strncmp(this-m_szStarName,earth,5) this-m_pAtmosphere-Render(); else*/ #ifdef _ANTI_LOCAL_TEST_ g_pS=this; ComPonentAntiAnliase-RenderTransferedObj(AntiTest);/this-m_sSphere-Render(); g_pS=NULL; #else this-m_sSphere-Render(); #endif if(0=strncmp(this-m_szStarName,earth,5) GLboolean bEnable=glIsEnabled(GL_BLEND); GLboolean bCullEnable=glIsEnabled(GL_CULL_FACE); if(!bEnable) glEnable(GL_BLEND); if(bCullEnable) glDisable(GL_CULL_FACE); /m_cBboard.render(); glDepthMask(false); /glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER ,0.0); glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA); /this-m_cLoadingBar.render(); /m_cBFace.render(); /m_cTestButton.render(); glScalef(1.1,1.1,1.1); /m_pAtmosphere-SetTexEnVMode(GL_BLEND); this-m_pAtmosphere-Render(); glDisable(GL_ALPHA_TEST); if(!bEnable) glDisable(GL_BLEND); if(bCullEnable) glEnable(GL_CULL_FACE); glDepthMask(true); glPopMatrix(); void Star:RenderSatellite() if(m_pvSatellite-size()=0) return; std:vector:iterator it=this-m_pvSatellite-begin(); std:vector:iterator end=this-m_pvSatellite-end(); /enable selecting /glInitNames(); Vector3D TargetToCamera=CameraMgr-getTargetPos()-CameraMgr-getPos(); TargetToCamera.normalize(); Vector3D objectToCamera; while(it!=end) objectToCamera=(*it)-getPos()-CameraMgr-getPos(); objectToCamera.normalize(); if(TargetToCamera.dot(objectToCamera)isSelectEnable() (*it)-startSelect(); (*it)-Render(); (*it)-endSelect(); else (*it)-Render(); it+; bool Star:HandleMessage(const Telegram void Star:setChildEnvMode(int model) if(m_pvSatellite-size()m_pvSatellite-begin(); std:vector:iterator

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论